From a7738eeb6459e56eb2edde2c09fb6ee776d93913 Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Wed, 10 Jun 2026 18:30:54 +0200 Subject: [PATCH] Pass around non-static logger instances and programmatic access to messages in-memory --- src/examples/IfcParseExamples.cpp | 2 +- src/ifcconvert/IfcConvert.cpp | 169 +++++++++--------- src/ifcconvert/validate_space_boundaries.cpp | 14 +- .../validate_storey_containment.cpp | 10 +- src/ifcconvert/validate_wall_connectivity.cpp | 16 +- src/ifcconvert/validation_utils.h | 11 +- src/ifcgeom/AbstractKernel.cpp | 4 +- src/ifcgeom/AbstractKernel.h | 17 +- src/ifcgeom/ConversionResult.cpp | 4 +- src/ifcgeom/ConversionResult.h | 4 +- src/ifcgeom/Converter.cpp | 21 +-- src/ifcgeom/Converter.h | 6 +- src/ifcgeom/GeometrySerializer.h | 7 +- src/ifcgeom/IfcGeomElement.h | 2 +- src/ifcgeom/Iterator.cpp | 54 +++--- src/ifcgeom/Iterator.h | 18 +- src/ifcgeom/Serializer.h | 9 +- src/ifcgeom/abstract_mapping.cpp | 4 +- src/ifcgeom/abstract_mapping.h | 11 +- src/ifcgeom/function_item_evaluator.cpp | 8 +- src/ifcgeom/function_item_evaluator.h | 8 +- src/ifcgeom/hybrid_kernel.h | 26 +-- src/ifcgeom/infra_sweep_helper.cpp | 22 +-- src/ifcgeom/infra_sweep_helper.h | 2 +- .../kernels/cgal/CgalConversionResult.cpp | 20 +-- .../kernels/cgal/CgalConversionResult.h | 6 +- src/ifcgeom/kernels/cgal/CgalKernel.cpp | 100 +++++------ src/ifcgeom/kernels/cgal/CgalKernel.h | 18 +- .../OpenCascadeConversionResult.cpp | 10 +- .../opencascade/OpenCascadeConversionResult.h | 2 +- .../kernels/opencascade/OpenCascadeKernel.cpp | 14 +- .../kernels/opencascade/OpenCascadeKernel.h | 6 +- .../kernels/opencascade/base_utils.cpp | 26 +-- .../kernels/opencascade/boolean_result.cpp | 6 +- .../kernels/opencascade/boolean_utils.cpp | 68 +++---- src/ifcgeom/kernels/opencascade/extrusion.cpp | 2 +- src/ifcgeom/kernels/opencascade/face.cpp | 28 +-- .../kernels/opencascade/faceset_helper.cpp | 6 +- src/ifcgeom/kernels/opencascade/layerset.cpp | 12 +- src/ifcgeom/kernels/opencascade/loft.cpp | 6 +- src/ifcgeom/kernels/opencascade/loop.cpp | 6 +- src/ifcgeom/kernels/opencascade/shell.cpp | 14 +- src/ifcgeom/kernels/opencascade/solid.cpp | 2 +- .../kernels/opencascade/sweep_along_curve.cpp | 4 +- .../kernels/opencascade/sweep_utils.cpp | 4 +- .../kernels/opencascade/wire_builder.cpp | 20 +-- .../kernels/opencascade/wire_utils.cpp | 34 ++-- src/ifcgeom/mapping/IfcAxis1Placement.cpp | 2 +- src/ifcgeom/mapping/IfcAxis2Placement2D.cpp | 2 +- src/ifcgeom/mapping/IfcAxis2Placement3D.cpp | 4 +- .../mapping/IfcAxis2PlacementLinear.cpp | 2 +- src/ifcgeom/mapping/IfcCShapeProfileDef.cpp | 2 +- src/ifcgeom/mapping/IfcCircle.cpp | 2 +- src/ifcgeom/mapping/IfcCompositeCurve.cpp | 6 +- src/ifcgeom/mapping/IfcCurveSegment.cpp | 34 ++-- src/ifcgeom/mapping/IfcEdge.cpp | 4 +- src/ifcgeom/mapping/IfcEllipse.cpp | 2 +- src/ifcgeom/mapping/IfcEllipseProfileDef.cpp | 2 +- src/ifcgeom/mapping/IfcExtrudedAreaSolid.cpp | 2 +- .../mapping/IfcExtrudedAreaSolidTapered.cpp | 2 +- src/ifcgeom/mapping/IfcGradientCurve.cpp | 8 +- src/ifcgeom/mapping/IfcHalfSpaceSolid.cpp | 2 +- src/ifcgeom/mapping/IfcIShapeProfileDef.cpp | 2 +- src/ifcgeom/mapping/IfcIndexedPolyCurve.cpp | 2 +- src/ifcgeom/mapping/IfcLShapeProfileDef.cpp | 4 +- src/ifcgeom/mapping/IfcObjectPlacement.cpp | 6 +- .../mapping/IfcOffsetCurveByDistance.cpp | 8 +- .../mapping/IfcOpenCrossProfileDef.cpp | 4 +- src/ifcgeom/mapping/IfcPolyLoop.cpp | 8 +- src/ifcgeom/mapping/IfcPolyline.cpp | 4 +- .../mapping/IfcRectangleHollowProfileDef.cpp | 2 +- .../mapping/IfcRectangleProfileDef.cpp | 2 +- .../mapping/IfcRoundedRectangleProfileDef.cpp | 2 +- .../mapping/IfcSectionedSolidHorizontal.cpp | 6 +- src/ifcgeom/mapping/IfcSectionedSurface.cpp | 6 +- .../mapping/IfcSegmentedReferenceCurve.cpp | 8 +- src/ifcgeom/mapping/IfcSweptDiskSolid.cpp | 4 +- src/ifcgeom/mapping/IfcTShapeProfileDef.cpp | 4 +- .../mapping/IfcTrapeziumProfileDef.cpp | 2 +- src/ifcgeom/mapping/IfcTrimmedCurve.cpp | 2 +- src/ifcgeom/mapping/IfcUShapeProfileDef.cpp | 2 +- src/ifcgeom/mapping/IfcZShapeProfileDef.cpp | 2 +- src/ifcgeom/mapping/mapping.cpp | 64 +++---- src/ifcgeom/mapping/mapping.h | 10 +- src/ifcgeom/taxonomy.cpp | 4 +- src/ifcgeomserver/IfcGeomServer.cpp | 2 +- .../ifcopenshell/__init__.py | 2 +- .../ifcopenshell/geom/main.py | 3 +- .../test/fixtures/ColumnPSetsOfSets.ifc | 2 +- .../test/test_create_shape.py | 20 +++ src/ifcparse/IfcAlignmentHelper.cpp | 26 +-- src/ifcparse/IfcCharacterDecoder.cpp | 2 +- src/ifcparse/IfcFile.cpp | 24 +-- src/ifcparse/IfcGlobalId.cpp | 4 +- src/ifcparse/IfcHierarchyHelper.cpp | 2 +- src/ifcparse/IfcHierarchyHelper.h | 4 +- src/ifcparse/IfcLogger.cpp | 58 +++--- src/ifcparse/IfcLogger.h | 108 +++++++---- src/ifcparse/IfcParse.cpp | 48 ++--- src/ifcparse/IfcSpfHeader.cpp | 2 +- src/ifcparse/parse_ifcxml.cpp | 24 +-- src/ifcwrap/IfcGeomWrapper.i | 30 ++-- src/ifcwrap/IfcParseWrapper.i | 42 ++++- src/ifcwrap/utils/type_conversion.i | 1 + src/ifcwrap/utils/typemaps_in.i | 18 ++ src/ifcwrap/utils/typemaps_out.i | 1 + src/serializers/ColladaSerializer.h | 4 +- src/serializers/GltfSerializer.cpp | 12 +- src/serializers/GltfSerializer.h | 2 +- src/serializers/HdfSerializer.cpp | 6 +- src/serializers/HdfSerializer.h | 2 +- src/serializers/IgesSerializer.h | 6 +- src/serializers/JsonSerializer.cpp | 9 +- src/serializers/JsonSerializer.h | 6 +- src/serializers/OpenCascadeBasedSerializer.h | 4 +- src/serializers/RocksDbSerializer.cpp | 12 +- src/serializers/RocksDbSerializer.h | 6 +- src/serializers/StepSerializer.h | 4 +- src/serializers/SvgSerializer.cpp | 36 ++-- src/serializers/SvgSerializer.h | 15 +- src/serializers/TtlWktSerializer.cpp | 8 +- src/serializers/TtlWktSerializer.h | 2 +- src/serializers/USDSerializer.cpp | 4 +- src/serializers/USDSerializer.h | 4 +- src/serializers/WavefrontObjSerializer.cpp | 4 +- src/serializers/WavefrontObjSerializer.h | 2 +- src/serializers/XmlSerializer.cpp | 9 +- src/serializers/XmlSerializer.h | 6 +- .../schema_dependent/JsonSerializer.cpp | 50 +++--- .../schema_dependent/JsonSerializer.h | 4 +- .../schema_dependent/XmlSerializer.cpp | 168 ++++++++--------- .../schema_dependent/XmlSerializer.h | 8 +- 132 files changed, 1029 insertions(+), 884 deletions(-) diff --git a/src/examples/IfcParseExamples.cpp b/src/examples/IfcParseExamples.cpp index e8ad950919..cf29151116 100644 --- a/src/examples/IfcParseExamples.cpp +++ b/src/examples/IfcParseExamples.cpp @@ -234,7 +234,7 @@ int main(int argc, char** argv) { } // Redirect the output (both progress and log) to stdout - Logger::SetOutput(&std::cout, &std::cout); + Logger::Root().SetOutput(&std::cout, &std::cout); // Parse the IFC file provided in argv[1] IfcParse::IfcFile file(argv[1]); diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index af5dcafdd8..ea72305cb6 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -174,7 +174,7 @@ bool file_exists(const std::string& filename) { static std::basic_stringstream log_stream; void write_log(bool); -void fix_quantities(IfcParse::IfcFile&, bool, bool, bool); +void fix_quantities(IfcParse::IfcFile&, bool, bool, bool, Logger& logger = Logger::Root()); std::string format_duration(time_t start, time_t end); /// @todo make the filters non-global @@ -204,7 +204,7 @@ size_t read_filters_from_file(const std::string&, inclusion_filter&, inclusion_t void parse_filter(geom_filter &, const std::vector&); std::vector setup_filters(const std::vector&, const std::string&); -bool init_input_file(const std::string& filename, IfcParse::IfcFile*& ifc_file, bool no_progress, bool mmap, bool bypass_properties=false); +bool init_input_file(const std::string& filename, IfcParse::IfcFile*& ifc_file, bool no_progress, bool mmap, bool bypass_properties=false, Logger& logger = Logger::Root()); // from https://stackoverflow.com/questions/31696328/boost-program-options-using-zero-parameter-options-multiple-times struct verbosity_counter { @@ -226,6 +226,7 @@ int main(int argc, char** argv) { typedef po::command_line_parser command_line_parser; typedef char char_t; #endif + Logger logger; inclusion_filter include_filter; inclusion_traverse_filter include_traverse_filter; @@ -492,15 +493,15 @@ int main(int argc, char** argv) { if (num_threads <= 0) { num_threads = std::thread::hardware_concurrency(); - Logger::Notice("SYS", 7, "Using " + std::to_string(num_threads) + " threads"); + logger.Notice("SYS", 7, "Using " + std::to_string(num_threads) + " threads"); } if (vmap.count("log-format") == 1) { boost::to_lower(log_format); if (log_format == "plain") { - Logger::OutputFormat(Logger::FMT_PLAIN); + logger.OutputFormat(Logger::FMT_PLAIN); } else if (log_format == "json") { - Logger::OutputFormat(Logger::FMT_JSON); + logger.OutputFormat(Logger::FMT_JSON); } else { cerr_ << "[Error] --log-format should be either plain or json" << std::endl; print_usage(); @@ -511,7 +512,7 @@ int main(int argc, char** argv) { if (!filter_filename.empty()) { size_t num_filters = read_filters_from_file(IfcUtil::path::to_utf8(filter_filename), include_filter, include_traverse_filter, exclude_filter, exclude_traverse_filter); if (num_filters) { - Logger::Notice("SYS", 8, boost::lexical_cast(num_filters) + " filters read from specifified file."); + logger.Notice("SYS", 8, boost::lexical_cast(num_filters) + " filters read from specifified file."); } else { cerr_ << "[Error] No filters read from specifified file.\n"; return EXIT_FAILURE; @@ -601,27 +602,27 @@ int main(int argc, char** argv) { if (vmap.count("log-file")) { log_fs.open(log_file.c_str(), std::ios::app); - Logger::SetOutput(quiet ? nullptr : &cout_, &log_fs); + logger.SetOutput(quiet ? nullptr : &cout_, &log_fs); } else { - Logger::SetOutput(quiet ? nullptr : &cout_, vcounter.count > 1 ? &cout_ : &log_stream); + logger.SetOutput(quiet ? nullptr : &cout_, vcounter.count > 1 ? &cout_ : &log_stream); } switch (vcounter.count) { case 0: - Logger::Verbosity(Logger::LOG_ERROR); + logger.Verbosity(Logger::LOG_ERROR); break; case 1: - Logger::Verbosity(Logger::LOG_NOTICE); + logger.Verbosity(Logger::LOG_NOTICE); break; case 2: - Logger::Verbosity(Logger::LOG_DEBUG); + logger.Verbosity(Logger::LOG_DEBUG); break; case 3: - Logger::Verbosity(Logger::LOG_PERF); + logger.Verbosity(Logger::LOG_PERF); break; case 4: - Logger::Verbosity(Logger::LOG_PERF); - Logger::PrintPerformanceStatsOnElement(true); + logger.Verbosity(Logger::LOG_PERF); + logger.PrintPerformanceStatsOnElement(true); break; } @@ -665,52 +666,52 @@ int main(int argc, char** argv) { if (output_extension == XML || output_extension == JSON) { int exit_code = EXIT_FAILURE; try { - if (init_input_file(IfcUtil::path::to_utf8(input_filename), ifc_file, no_progress || quiet, mmap)) { + if (init_input_file(IfcUtil::path::to_utf8(input_filename), ifc_file, no_progress || quiet, mmap, false, logger)) { time_t start, end; time(&start); if (output_extension == XML) { - XmlSerializer s(ifc_file, IfcUtil::path::to_utf8(output_temp_filename)); - Logger::Status("Writing XML output..."); + XmlSerializer s(ifc_file, IfcUtil::path::to_utf8(output_temp_filename), logger); + logger.Status("Writing XML output..."); s.finalize(); } else { #ifdef WITH_GLTF - JsonSerializer s(ifc_file, IfcUtil::path::to_utf8(output_temp_filename), JsonSerializer::JSON_DIALECT_CREOOX); - Logger::Status("Writing JSON output..."); + JsonSerializer s(ifc_file, IfcUtil::path::to_utf8(output_temp_filename), JsonSerializer::JSON_DIALECT_CREOOX, logger); + logger.Status("Writing JSON output..."); s.finalize(); #endif } time(&end); - Logger::Status("Done! Conversion took " + format_duration(start, end)); + logger.Status("Done! Conversion took " + format_duration(start, end)); IfcUtil::path::rename_file(IfcUtil::path::to_utf8(output_temp_filename), IfcUtil::path::to_utf8(output_filename)); exit_code = EXIT_SUCCESS; } } catch (const std::exception& e) { - Logger::Error("SYS", 9, e); + logger.Error("SYS", 9, e); } write_log(!quiet); return exit_code; } else if (output_extension == IFC) { int exit_code = EXIT_FAILURE; try { - if (init_input_file(IfcUtil::path::to_utf8(input_filename), ifc_file, no_progress || quiet, mmap)) { + if (init_input_file(IfcUtil::path::to_utf8(input_filename), ifc_file, no_progress || quiet, mmap, false, logger)) { time_t start, end; time(&start); std::ofstream fs(output_filename.c_str()); if (fs.is_open()) { if (vmap.count("calculate-quantities")) { - fix_quantities(*ifc_file, no_progress, quiet, stderr_progress); + fix_quantities(*ifc_file, no_progress, quiet, stderr_progress, logger); } fs << *ifc_file; exit_code = EXIT_SUCCESS; } else { - Logger::Error("SYS", 10, "Unable to open output file for writing"); + logger.Error("SYS", 10, "Unable to open output file for writing"); } time(&end); - Logger::Status("Done! Writing IFC took " + format_duration(start, end)); + logger.Status("Done! Writing IFC took " + format_duration(start, end)); } } catch (const std::exception& e) { - Logger::Error("SYS", 11, e); + logger.Error("SYS", 11, e); } write_log(!quiet); return exit_code; @@ -722,26 +723,26 @@ int main(int argc, char** argv) { if (vmap.count("stream")) { time_t start, end; time(&start); - RocksDbSerializer s(IfcUtil::path::to_utf8(input_filename), IfcUtil::path::to_utf8(output_filename), true); - Logger::Status("Populating RocksDB Key-Value store..."); + RocksDbSerializer s(IfcUtil::path::to_utf8(input_filename), IfcUtil::path::to_utf8(output_filename), true, logger); + logger.Status("Populating RocksDB Key-Value store..."); s.finalize(); time(&end); - Logger::Status("Done! Conversion took " + format_duration(start, end)); + logger.Status("Done! Conversion took " + format_duration(start, end)); exit_code = EXIT_SUCCESS; } else { - if (init_input_file(IfcUtil::path::to_utf8(input_filename), ifc_file, no_progress || quiet, mmap)) { + if (init_input_file(IfcUtil::path::to_utf8(input_filename), ifc_file, no_progress || quiet, mmap, false, logger)) { time_t start, end; time(&start); - RocksDbSerializer s(ifc_file, IfcUtil::path::to_utf8(output_filename)); - Logger::Status("Populating RocksDB Key-Value store..."); + RocksDbSerializer s(ifc_file, IfcUtil::path::to_utf8(output_filename), logger); + logger.Status("Populating RocksDB Key-Value store..."); s.finalize(); time(&end); - Logger::Status("Done! Conversion took " + format_duration(start, end)); + logger.Status("Done! Conversion took " + format_duration(start, end)); exit_code = EXIT_SUCCESS; } } } catch (const std::exception& e) { - Logger::Error("SYS", 12, e); + logger.Error("SYS", 12, e); } write_log(!quiet); return exit_code; @@ -761,9 +762,9 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } - if (!entity_filter.entity_names.empty()) { entity_filter.update_description(); Logger::Notice("SYS", 13, entity_filter.description); } - if (!layer_filter.values.empty()) { layer_filter.update_description(); Logger::Notice("SYS", 14, layer_filter.description); } - if (!attribute_filter.attribute_name.empty()) { attribute_filter.update_description(); Logger::Notice("SYS", 15, attribute_filter.description); } + if (!entity_filter.entity_names.empty()) { entity_filter.update_description(); logger.Notice("SYS", 13, entity_filter.description); } + if (!layer_filter.values.empty()) { layer_filter.update_description(); logger.Notice("SYS", 14, layer_filter.description); } + if (!attribute_filter.attribute_name.empty()) { attribute_filter.update_description(); logger.Notice("SYS", 15, attribute_filter.description); } #ifdef _MSC_VER if (output_extension == DAE || output_extension == STP || output_extension == IGS) { @@ -828,39 +829,39 @@ int main(int argc, char** argv) { if (output_extension == OBJ) { // Do not use temp file for MTL as it's such a small file. const path_t mtl_filename = change_extension(output_filename, MTL); - serializer = boost::make_shared(IfcUtil::path::to_utf8(output_temp_filename), IfcUtil::path::to_utf8(mtl_filename), geometry_settings, serializer_settings); + serializer = boost::make_shared(IfcUtil::path::to_utf8(output_temp_filename), IfcUtil::path::to_utf8(mtl_filename), geometry_settings, serializer_settings, logger); #ifdef WITH_OPENCOLLADA } else if (output_extension == DAE) { - serializer = boost::make_shared(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings); + serializer = boost::make_shared(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings, logger); #endif #ifdef WITH_GLTF } else if (output_extension == GLB) { - serializer = boost::make_shared(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings); + serializer = boost::make_shared(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings, logger); #endif #ifdef WITH_USD } else if (output_extension == USD || output_extension == USDA || output_extension == USDC) { - serializer = boost::make_shared(IfcUtil::path::to_utf8(output_filename), geometry_settings, serializer_settings); + serializer = boost::make_shared(IfcUtil::path::to_utf8(output_filename), geometry_settings, serializer_settings, logger); #endif #ifdef IFOPSH_WITH_OPENCASCADE } else if (output_extension == STP) { - serializer = boost::make_shared(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings); + serializer = boost::make_shared(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings, logger); } else if (output_extension == IGS) { #if OCC_VERSION_HEX < 0x60900 // According to https://tracker.dev.opencascade.org/view.php?id=25689 something has been fixed in 6.9.0 IGESControl_Controller::Init(); // work around Open Cascade bug #endif - serializer = boost::make_shared(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings); + serializer = boost::make_shared(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings, logger); } else if (output_extension == SVG) { geometry_settings.get().value = ifcopenshell::geometry::settings::NATIVE; - serializer = boost::make_shared(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings); + serializer = boost::make_shared(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings, logger); #ifdef WITH_HDF5 } else if (output_extension == HDF) { geometry_settings.get().value = ifcopenshell::geometry::settings::NATIVE; - serializer = boost::make_shared(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings); + serializer = boost::make_shared(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings, false, logger); #endif #endif } else if (output_extension == TTL) { - serializer = boost::make_shared(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings); + serializer = boost::make_shared(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings, logger); } else { cerr_ << "[Error] Unknown output filename extension '" << output_extension << "'\n"; write_log(!quiet); @@ -871,13 +872,13 @@ int main(int argc, char** argv) { const bool is_tesselated = serializer->isTesselated(); // isTesselated() doesn't change at run-time if (!is_tesselated) { if (geometry_settings.get().get()) { - Logger::Notice("SYS", 16, "Weld vertices setting ignored when writing non-tesselated output"); + logger.Notice("SYS", 16, "Weld vertices setting ignored when writing non-tesselated output"); } if (geometry_settings.get().get()) { - Logger::Notice("SYS", 17, "Generate UVs setting ignored when writing non-tesselated output"); + logger.Notice("SYS", 17, "Generate UVs setting ignored when writing non-tesselated output"); } if (center_model || center_model_geometry) { - Logger::Notice("SYS", 18, "Centering/offsetting model setting ignored when writing non-tesselated output"); + logger.Notice("SYS", 18, "Centering/offsetting model setting ignored when writing non-tesselated output"); } geometry_settings.get().value = ifcopenshell::geometry::settings::NATIVE; @@ -895,7 +896,7 @@ int main(int argc, char** argv) { // @nb last argument true -> bypass_properties which are not read by any of the geometry serializers // XML, RocksDB, IFC are already special-cased above // SVG requires properties for IfcAnnotation/DRAWING properties - if (!init_input_file(IfcUtil::path::to_utf8(input_filename), ifc_file, no_progress || quiet, mmap, output_extension != SVG)) { + if (!init_input_file(IfcUtil::path::to_utf8(input_filename), ifc_file, no_progress || quiet, mmap, output_extension != SVG, logger)) { write_log(!quiet); serializer.reset(); IfcUtil::path::delete_file(IfcUtil::path::to_utf8(output_temp_filename)); /**< @todo Windows Unicode support */ @@ -903,9 +904,9 @@ int main(int argc, char** argv) { } if (vmap.count("log-file")) { - Logger::SetOutput(quiet ? nullptr : &cout_, &log_fs); + logger.SetOutput(quiet ? nullptr : &cout_, &log_fs); } else { - Logger::SetOutput(quiet ? nullptr : &cout_, vcounter.count > 1 ? &cout_ : &log_stream); + logger.SetOutput(quiet ? nullptr : &cout_, vcounter.count > 1 ? &cout_ : &log_stream); } if (model_rotation) { @@ -920,13 +921,13 @@ int main(int argc, char** argv) { std::stringstream msg; msg << "Using model rotation (" << rotation[0] << "," << rotation[1] << "," << rotation[2] << "," << rotation[3] << ")"; - Logger::Notice("SYS", 19, msg.str()); + logger.Notice("SYS", 19, msg.str()); geometry_settings.get().value = rotation; } if (model_offset && (center_model || center_model_geometry)) { - Logger::Notice("GEO", 22, "--model-offset ignored with --center-model or --center-model-geometry"); + logger.Notice("GEO", 22, "--model-offset ignored with --center-model or --center-model-geometry"); } if (model_offset && !(center_model || center_model_geometry)) { @@ -941,7 +942,7 @@ int main(int argc, char** argv) { std::stringstream msg; msg << std::setprecision(std::numeric_limits::max_digits10) << "Using model offset (" << offset[0] << "," << offset[1] << "," << offset[2] << ")"; - Logger::Notice("SYS", 20, msg.str()); + logger.Notice("SYS", 20, msg.str()); geometry_settings.get().value = offset; } @@ -949,17 +950,17 @@ int main(int argc, char** argv) { if (is_tesselated && (center_model || center_model_geometry)) { std::vector offset(3); - IfcGeom::Iterator tmp_context_iterator(ifcopenshell::geometry::kernels::construct(ifc_file, geometry_kernel, geometry_settings), geometry_settings, ifc_file, filter_funcs, num_threads); + IfcGeom::Iterator tmp_context_iterator(ifcopenshell::geometry::kernels::construct(ifc_file, geometry_kernel, geometry_settings, logger), geometry_settings, ifc_file, filter_funcs, num_threads, logger); time_t start, end; time(&start); - if (!quiet) Logger::Status("Computing bounds..."); + if (!quiet) logger.Status("Computing bounds..."); if (center_model_geometry) { if (!tmp_context_iterator.initialize()) { /// @todo It would be nice to know and print separate error prints for a case where we found no entities /// and for a case we found no entities that satisfy our filtering criteria. - Logger::Notice("GEO", 23, "No geometrical elements found or none successfully converted"); + logger.Notice("GEO", 23, "No geometrical elements found or none successfully converted"); serializer.reset(); IfcUtil::path::delete_file(IfcUtil::path::to_utf8(output_temp_filename)); write_log(!quiet); @@ -970,7 +971,7 @@ int main(int argc, char** argv) { tmp_context_iterator.compute_bounds(center_model_geometry); time(&end); - if (!quiet) Logger::Status("Done ! Bounds computed in " + format_duration(start, end)); + if (!quiet) logger.Status("Done ! Bounds computed in " + format_duration(start, end)); auto center = (tmp_context_iterator.bounds_min().ccomponents() + tmp_context_iterator.bounds_max().ccomponents()) * 0.5; offset[0] = -center(0); @@ -979,7 +980,7 @@ int main(int argc, char** argv) { std::stringstream msg; msg << std::setprecision (std::numeric_limits::max_digits10) << "Using model offset (" << offset[0] << "," << offset[1] << "," << offset[2] << ")"; - Logger::Notice("SYS", 21, msg.str()); + logger.Notice("SYS", 21, msg.str()); geometry_settings.get().value = offset; } @@ -995,7 +996,7 @@ int main(int argc, char** argv) { std::unique_ptr context_iterator; if (!elems_from_adaptor) { - context_iterator.reset(new IfcGeom::Iterator(ifcopenshell::geometry::kernels::construct(ifc_file, geometry_kernel, geometry_settings), geometry_settings, ifc_file, filter_funcs, num_threads)); + context_iterator.reset(new IfcGeom::Iterator(ifcopenshell::geometry::kernels::construct(ifc_file, geometry_kernel, geometry_settings, logger), geometry_settings, ifc_file, filter_funcs, num_threads, logger)); } #if defined(WITH_HDF5) && defined(IFOPSH_WITH_OPENCASCADE) @@ -1004,17 +1005,17 @@ int main(int argc, char** argv) { if (!vmap.count("cache-file")) { cache_file = input_filename + CACHE + HDF; } - cache.reset(new HdfSerializer(IfcUtil::path::to_utf8(cache_file), geometry_settings, serializer_settings)); + cache.reset(new HdfSerializer(IfcUtil::path::to_utf8(cache_file), geometry_settings, serializer_settings, false, logger)); context_iterator->set_cache(cache.get()); } #endif - Logger::Message(Logger::LOG_PERF, "GEO", 24, "file geometry conversion"); + logger.Message(Logger::LOG_PERF, "GEO", 24, "file geometry conversion"); if (context_iterator && !context_iterator->initialize()) { /// @todo It would be nice to know and print separate error prints for a case where we found no entities /// and for a case we found no entities that satisfy our filtering criteria. - Logger::Notice("GEO", 25, "No geometrical elements found or none successfully converted"); + logger.Notice("GEO", 25, "No geometrical elements found or none successfully converted"); serializer.reset(); IfcUtil::path::delete_file(IfcUtil::path::to_utf8(output_temp_filename)); write_log(!quiet); @@ -1033,7 +1034,7 @@ int main(int argc, char** argv) { static_cast(serializer.get())->setSectionHeightsFromStoreys(); } } else if (vmap.count("section-height") != 0) { - Logger::Notice("SYS", 22, "Overriding section height"); + logger.Notice("SYS", 22, "Overriding section height"); static_cast(serializer.get())->setSectionHeight(section_height); } if (vmap.count("print-space-names") != 0) { @@ -1111,7 +1112,7 @@ int main(int argc, char** argv) { int old_progress = quiet ? 0 : -1; if (!quiet) { - Logger::Status("Creating geometry..."); + logger.Status("Creating geometry..."); } // The functions IfcGeom::Iterator::get() and IfcGeom::Iterator::next() @@ -1156,10 +1157,10 @@ int main(int argc, char** argv) { if (stderr_progress) cerr_ << std::flush; } else if (vcounter.count == 2) { - Logger::Message(Logger::LOG_DEBUG, "SYS", 23, "Progress " + boost::lexical_cast(progress)); + logger.Message(Logger::LOG_DEBUG, "SYS", 23, "Progress " + boost::lexical_cast(progress)); } else { progress = progress / 2; - if (old_progress != progress) Logger::ProgressBar(progress); + if (old_progress != progress) logger.ProgressBar(progress); old_progress = progress; } } @@ -1188,7 +1189,7 @@ int main(int argc, char** argv) { } } else { const std::string task = ((num_threads == 1) ? "creating" : "writing"); - Logger::Status("\rDone " + task + " geometry (" + boost::lexical_cast(num_created) + + logger.Status("\rDone " + task + " geometry (" + boost::lexical_cast(num_created) + " objects) "); } @@ -1196,7 +1197,7 @@ int main(int argc, char** argv) { // Make sure the dtor is explicitly run here (e.g. output files are closed before renaming them). serializer.reset(); - Logger::Message(Logger::LOG_PERF, "GEO", 26, "done file geometry conversion"); + logger.Message(Logger::LOG_PERF, "GEO", 26, "done file geometry conversion"); bool successful; if(output_extension == USD || output_extension == USDC || output_extension == USDA) { @@ -1214,13 +1215,13 @@ int main(int argc, char** argv) { output_temp_filename << "' for the conversion result."; } - if (geometry_settings.get().get() && Logger::MaxSeverity() >= Logger::LOG_ERROR) { - Logger::Error("SYS", 24, "Errors encountered during processing."); + if (geometry_settings.get().get() && logger.MaxSeverity() >= Logger::LOG_ERROR) { + logger.Error("SYS", 24, "Errors encountered during processing."); successful = false; } - if (Logger::Verbosity() == Logger::LOG_PERF) { - Logger::PrintPerformanceStats(); + if (logger.Verbosity() == Logger::LOG_PERF) { + logger.PrintPerformanceStats(); } write_log(!quiet); @@ -1228,7 +1229,7 @@ int main(int argc, char** argv) { time(&end); if (!quiet) { - Logger::Status("\nConversion took " + format_duration(start, end)); + logger.Status("\nConversion took " + format_duration(start, end)); } return successful ? EXIT_SUCCESS : EXIT_FAILURE; @@ -1266,11 +1267,11 @@ void write_log(bool header) { #include -bool init_input_file(const std::string& filename, IfcParse::IfcFile*& ifc_file, bool no_progress, bool mmap, bool bypass_properties) { +bool init_input_file(const std::string& filename, IfcParse::IfcFile*& ifc_file, bool no_progress, bool mmap, bool bypass_properties, Logger& logger) { time_t start, end; // Prevent IfcFile::Init() prints by setting output to null temporarily - if (no_progress) { Logger::SetOutput(NULL, &log_stream); } + if (no_progress) { logger.SetOutput(NULL, &log_stream); } time(&start); @@ -1308,13 +1309,13 @@ bool init_input_file(const std::string& filename, IfcParse::IfcFile*& ifc_file, } if (!ifc_file || !ifc_file->good()) { - Logger::Error("SYN", 1, "Unable to parse input file '" + filename + "'"); + logger.Error("SYN", 1, "Unable to parse input file '" + filename + "'"); return false; } time(&end); - if (no_progress) { Logger::SetOutput(&cout_, &log_stream); } - else { Logger::Status("Parsing input file took " + format_duration(start, end)); } + if (no_progress) { logger.SetOutput(&cout_, &log_stream); } + else { logger.Status("Parsing input file took " + format_duration(start, end)); } return true; @@ -1533,7 +1534,7 @@ namespace latebound_access { } } -void fix_quantities(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool stderr_progress) { +void fix_quantities(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool stderr_progress, Logger& logger) { { auto delete_reversed = [&f](const aggregate_of_instance::ptr& insts) { if (!insts) { @@ -1588,7 +1589,7 @@ void fix_quantities(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool std settings.get().value = true; settings.get().value = ifcopenshell::geometry::settings::NATIVE; - IfcGeom::Iterator context_iterator(ifcopenshell::geometry::kernels::construct(&f, "opencascade", settings), settings, &f, {}, 1); + IfcGeom::Iterator context_iterator(ifcopenshell::geometry::kernels::construct(&f, "opencascade", settings, logger), settings, &f, {}, 1, logger); if (!context_iterator.initialize()) { return; @@ -1716,7 +1717,7 @@ void fix_quantities(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool std cerr_ << std::flush; } else { const int progress = context_iterator.progress() / 2; - if (old_progress != progress) Logger::ProgressBar(progress); + if (old_progress != progress) logger.ProgressBar(progress); old_progress = progress; } } @@ -1732,7 +1733,7 @@ void fix_quantities(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool std if (stderr_progress) cerr_ << std::flush; } else { - Logger::Status("\rDone writing quantities for " + boost::lexical_cast(num_created) + + logger.Status("\rDone writing quantities for " + boost::lexical_cast(num_created) + " objects "); } diff --git a/src/ifcconvert/validate_space_boundaries.cpp b/src/ifcconvert/validate_space_boundaries.cpp index ee3dc97a5e..6572d1d659 100644 --- a/src/ifcconvert/validate_space_boundaries.cpp +++ b/src/ifcconvert/validate_space_boundaries.cpp @@ -18,8 +18,8 @@ typedef CGAL::AABB_traits Traits; typedef CGAL::AABB_tree Tree; typedef Tree::Point_and_primitive_id Point_and_primitive_id; -void fix_spaceboundaries(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool stderr_progress) { - intersection_validator v(f, { "IfcWall", "IfcSpace", "IfcSlab", "IfcCovering" }, 1.e-5, no_progress, quiet, stderr_progress); +void fix_spaceboundaries(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool stderr_progress, Logger& logger = Logger::Root()) { + intersection_validator v(f, { "IfcWall", "IfcSpace", "IfcSlab", "IfcCovering" }, 1.e-5, no_progress, quiet, stderr_progress, logger); auto rels = f.instances_by_type("IfcRelSpaceBoundary"); @@ -54,7 +54,7 @@ void fix_spaceboundaries(IfcParse::IfcFile& f, bool no_progress, bool quiet, boo settings.get().value = ifcopenshell::geometry::settings::NATIVE; settings.get().value = true; - ifcopenshell::geometry::Converter c("cgal", &f2, settings); + ifcopenshell::geometry::Converter c(ifcopenshell::geometry::kernels::construct(&f2, "cgal", settings, logger), &f2, settings, logger); std::map, std::vector> elem_to_space_boundary_coords; @@ -81,7 +81,7 @@ void fix_spaceboundaries(IfcParse::IfcFile& f, bool no_progress, bool quiet, boo std::set< std::set > guid_pairs_visited; - v([&rel_by_space_elem, &elem_to_space_boundary_coords, &guid_pairs_visited](const intersection_validator::Box& a, const intersection_validator::Box& b) { + v([&logger, &rel_by_space_elem, &elem_to_space_boundary_coords, &guid_pairs_visited](const intersection_validator::Box& a, const intersection_validator::Box& b) { std::ostringstream ss; // ss << id_map[a.id()]->first->data().toString() << "x" << id_map[b.id()]->first->data().toString() << std::endl; // auto x = id_map[a.id()]->second * id_map[b.id()]->second; @@ -128,7 +128,7 @@ void fix_spaceboundaries(IfcParse::IfcFile& f, bool no_progress, bool quiet, boo auto itelem = elem_to_space_boundary_coords.find({ Aguid, Bguid }); if (itelem == elem_to_space_boundary_coords.end()) { - Logger::Error("VAL", 1, "Missing space boundary relationship " + Aguid + " " + Bguid); + logger.Error("VAL", 1, "Missing space boundary relationship " + Aguid + " " + Bguid); return; } @@ -141,7 +141,7 @@ void fix_spaceboundaries(IfcParse::IfcFile& f, bool no_progress, bool quiet, boo bool valid = *std::max_element(distances.begin(), distances.end()) < 0.4; if (!valid) { - Logger::Error("VAL", 2, "Wrong connection geometry " + Aguid + " " + Bguid); + logger.Error("VAL", 2, "Wrong connection geometry " + Aguid + " " + Bguid); } /*{ @@ -178,7 +178,7 @@ void fix_spaceboundaries(IfcParse::IfcFile& f, bool no_progress, bool quiet, boo auto g1 = n.substr(0, 22); auto g2 = n.substr(23); if (is_wall_space_or_slab(g1) && is_wall_space_or_slab(g2) && guid_pairs_visited.find({ g1, g2 }) == guid_pairs_visited.end()) { - Logger::Error("VAL", 3, "Space boundary for non-bounding geometry " + g1 + " " + g2); + logger.Error("VAL", 3, "Space boundary for non-bounding geometry " + g1 + " " + g2); } } } diff --git a/src/ifcconvert/validate_storey_containment.cpp b/src/ifcconvert/validate_storey_containment.cpp index a0a360b1f6..7c40cce60a 100644 --- a/src/ifcconvert/validate_storey_containment.cpp +++ b/src/ifcconvert/validate_storey_containment.cpp @@ -9,7 +9,7 @@ #include -void fix_storeycontainment(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool stderr_progress) { +void fix_storeycontainment(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool stderr_progress, Logger& logger = Logger::Root()) { ifcopenshell::geometry::Settings settings; settings.get().value = false; @@ -23,7 +23,7 @@ void fix_storeycontainment(IfcParse::IfcFile& f, bool no_progress, bool quiet, b IfcGeom::entity_filter(false, false, {"IfcOpeningElement", "IfcSpace"}) }; - IfcGeom::Iterator context_iterator("cgal", settings, &f, no_openings_and_spaces, 1); + IfcGeom::Iterator context_iterator(ifcopenshell::geometry::kernels::construct(&f, "cgal", settings, logger), settings, &f, no_openings_and_spaces, 1, logger); auto get_elevation = [](const IfcUtil::IfcBaseClass* a) { return ((const IfcUtil::IfcBaseEntity*)a)->get_value("Elevation", 0.); @@ -198,7 +198,7 @@ void fix_storeycontainment(IfcParse::IfcFile& f, bool no_progress, bool quiet, b auto s = geom_object->product()->get_value("GlobalId"); auto s1 = ((IfcUtil::IfcBaseEntity*)storeys_sorted[calc_idx])->get_value("GlobalId"); auto s2 = ((IfcUtil::IfcBaseEntity*)elem_to_storey[geom_object->product()])->get_value("GlobalId"); - Logger::Error("VAL", 4, "Element " + s + " contained in " + s2 + " located on " + s1); + logger.Error("VAL", 4, "Element " + s + " contained in " + s2 + " located on " + s1); } if (!no_progress) { @@ -214,7 +214,7 @@ void fix_storeycontainment(IfcParse::IfcFile& f, bool no_progress, bool quiet, b std::cerr << std::flush; } else { const int progress = context_iterator.progress() / 2; - if (old_progress != progress) Logger::ProgressBar(progress); + if (old_progress != progress) logger.ProgressBar(progress); old_progress = progress; } } @@ -230,7 +230,7 @@ void fix_storeycontainment(IfcParse::IfcFile& f, bool no_progress, bool quiet, b if (stderr_progress) std::cerr << std::flush; } else { - Logger::Status("\rDone fixing space boundaries for " + boost::lexical_cast(num_created) + + logger.Status("\rDone fixing space boundaries for " + boost::lexical_cast(num_created) + " objects "); } } diff --git a/src/ifcconvert/validate_wall_connectivity.cpp b/src/ifcconvert/validate_wall_connectivity.cpp index cb1251f117..28e8849749 100644 --- a/src/ifcconvert/validate_wall_connectivity.cpp +++ b/src/ifcconvert/validate_wall_connectivity.cpp @@ -9,8 +9,8 @@ using namespace ifcopenshell::geometry; -void fix_wallconnectivity(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool stderr_progress) { - intersection_validator v(f, { "IfcWall" }, 1.e-3, no_progress, quiet, stderr_progress); +void fix_wallconnectivity(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool stderr_progress, Logger& logger = Logger::Root()) { + intersection_validator v(f, { "IfcWall" }, 1.e-3, no_progress, quiet, stderr_progress, logger); ifcopenshell::geometry::Settings settings; @@ -24,7 +24,7 @@ void fix_wallconnectivity(IfcParse::IfcFile& f, bool no_progress, bool quiet, bo settings.get().value = true; settings.get().value = false; - ifcopenshell::geometry::Converter c("cgal", &f, settings); + ifcopenshell::geometry::Converter c(ifcopenshell::geometry::kernels::construct(&f, "cgal", settings, logger), &f, settings, logger); auto rels = f.instances_by_type("IfcRelConnectsPathElements"); std::map, const IfcUtil::IfcBaseClass*> rel_by_elem; @@ -39,7 +39,7 @@ void fix_wallconnectivity(IfcParse::IfcFile& f, bool no_progress, bool quiet, bo double total_nef_intersection_time = 0.; double conversion_to_poly = 0.; - v([&c, &rel_by_elem, &rels_encounted, &total_nef_intersection_time, &conversion_to_poly](const intersection_validator::Box& a, const intersection_validator::Box& b) { + v([&logger, &c, &rel_by_elem, &rels_encounted, &total_nef_intersection_time, &conversion_to_poly](const intersection_validator::Box& a, const intersection_validator::Box& b) { auto A = a.handle()->first; auto B = b.handle()->first; @@ -169,21 +169,21 @@ void fix_wallconnectivity(IfcParse::IfcFile& f, bool no_progress, bool quiet, bo if (a_type != atype_computed || b_type != btype_computed) { if (rel) { - Logger::Error("VAL", 5, std::string("Connection type ") + atype_computed + " " + btype_computed + " for:", rel); + logger.Error("VAL", 5, std::string("Connection type ") + atype_computed + " " + btype_computed + " for:", rel); } else { auto A_str = A->get_value("GlobalId"); auto B_str = B->get_value("GlobalId"); - Logger::Error("VAL", 6, "No connection for adjacent " + A_str + " " + B_str); + logger.Error("VAL", 6, "No connection for adjacent " + A_str + " " + B_str); } } }); - std::for_each(rels->begin(), rels->end(), [&rels_encounted, &v](const IfcUtil::IfcBaseClass* rel) { + std::for_each(rels->begin(), rels->end(), [&logger, &rels_encounted, &v](const IfcUtil::IfcBaseClass* rel) { if (rels_encounted.find(rel) == rels_encounted.end()) { auto x = (IfcUtil::IfcBaseEntity*)((IfcUtil::IfcBaseEntity*)rel)->get_value("RelatingElement"); auto y = (IfcUtil::IfcBaseEntity*)((IfcUtil::IfcBaseEntity*)rel)->get_value("RelatedElement"); if (v.successfully_processed.find(x) != v.successfully_processed.end() && v.successfully_processed.find(y) != v.successfully_processed.end()) { - Logger::Error("VAL", 7, "Connection for non-adjacent walls", rel); + logger.Error("VAL", 7, "Connection for non-adjacent walls", rel); } } }); diff --git a/src/ifcconvert/validation_utils.h b/src/ifcconvert/validation_utils.h index c6952324a0..5a98c07326 100644 --- a/src/ifcconvert/validation_utils.h +++ b/src/ifcconvert/validation_utils.h @@ -3,6 +3,7 @@ #include "../ifcgeom/kernels/cgal/CgalKernel.h" #include "../ifcgeom/IfcGeomFilter.h" #include "../ifcgeom/Iterator.h" +#include "../ifcgeom/hybrid_kernel.h" #include #include @@ -445,7 +446,7 @@ struct intersection_validator { std::set successfully_processed; - intersection_validator(IfcParse::IfcFile& f, std::initializer_list entities, double eps, bool no_progress, bool quiet, bool stderr_progress) { + intersection_validator(IfcParse::IfcFile& f, std::initializer_list entities, double eps, bool no_progress, bool quiet, bool stderr_progress, Logger& logger = Logger::Root()) { ifcopenshell::geometry::Settings settings; settings.get().value = false; @@ -459,7 +460,7 @@ struct intersection_validator { IfcGeom::entity_filter(true, false, entities) }; - IfcGeom::Iterator context_iterator("cgal", settings, &f, spaces_and_walls, 1); + IfcGeom::Iterator context_iterator(ifcopenshell::geometry::kernels::construct(&f, "cgal", settings, logger), settings, &f, spaces_and_walls, 1, logger); if (!context_iterator.initialize()) { return; @@ -562,7 +563,7 @@ struct intersection_validator { std::cerr << std::flush; } else { const int progress = context_iterator.progress() / 2; - if (old_progress != progress) Logger::ProgressBar(progress); + if (old_progress != progress) logger.ProgressBar(progress); old_progress = progress; } } @@ -578,7 +579,7 @@ struct intersection_validator { if (stderr_progress) std::cerr << std::flush; } else { - Logger::Status("\rDone fixing space boundaries for " + boost::lexical_cast(num_created) + + logger.Status("\rDone fixing space boundaries for " + boost::lexical_cast(num_created) + " objects "); } @@ -599,4 +600,4 @@ struct intersection_validator { } }; -#endif \ No newline at end of file +#endif diff --git a/src/ifcgeom/AbstractKernel.cpp b/src/ifcgeom/AbstractKernel.cpp index 0e8baa14a1..2031197ee3 100644 --- a/src/ifcgeom/AbstractKernel.cpp +++ b/src/ifcgeom/AbstractKernel.cpp @@ -20,7 +20,7 @@ bool ifcopenshell::geometry::kernels::AbstractKernel::convert(const taxonomy::pt auto it = cache_.find(item); if (it != cache_.end()) { results = it->second; - Logger::Notice("SYS", 25, "Cache hit #" + std::to_string(item->instance->as()->id()) + + logger_.Notice("SYS", 25, "Cache hit #" + std::to_string(item->instance->as()->id()) + " -> #" + std::to_string(it->first->instance->as()->id())); return true; } @@ -30,7 +30,7 @@ bool ifcopenshell::geometry::kernels::AbstractKernel::convert(const taxonomy::pt try { return fn(); } catch (std::exception& e) { - Logger::Error("GEO", 27, e, item->instance); + logger_.Error("GEO", 27, e, item->instance); return false; } catch (...) { // @todo we can't log OCCT exceptions here, can we do some reraising to solve this? diff --git a/src/ifcgeom/AbstractKernel.h b/src/ifcgeom/AbstractKernel.h index 9e3467c58b..400c2b38f6 100644 --- a/src/ifcgeom/AbstractKernel.h +++ b/src/ifcgeom/AbstractKernel.h @@ -64,13 +64,15 @@ namespace ifcopenshell { protected: std::string geometry_library_; Settings settings_; + Logger& logger_; public: bool propagate_exceptions = false; bool partial_success_is_success = true; - AbstractKernel(const std::string& geometry_library, const Settings& settings) + AbstractKernel(const std::string& geometry_library, const Settings& settings, Logger& logger = Logger::Root()) : geometry_library_(geometry_library) - , settings_(settings) {} + , settings_(settings) + , logger_(logger) {} virtual ~AbstractKernel() = default; @@ -79,6 +81,7 @@ namespace ifcopenshell { const std::string& geometry_library() const { return geometry_library_; } + Logger& logger() const { return logger_; } virtual bool supports_boolean_operations() const = 0; @@ -154,7 +157,7 @@ namespace { if (item->instance) { created_from = " (created from " + item->instance->declaration().name() + ")"; } - Logger::Error("UNS", 1, "No support for " + ifcopenshell::geometry::taxonomy::kind_to_string(item->kind()) + created_from + " in kernel " + kernel->geometry_library()); + kernel->logger().Error("UNS", 1, "No support for " + ifcopenshell::geometry::taxonomy::kind_to_string(item->kind()) + created_from + " in kernel " + kernel->geometry_library()); return false; } }; @@ -178,7 +181,7 @@ namespace { if (item->instance) { created_from = " (created from " + item->instance->declaration().name() + ")"; } - Logger::Error("UNS", 2, "No support (after considering item upgrade) for " + ifcopenshell::geometry::taxonomy::kind_to_string(item->kind()) + created_from + " in kernel " + kernel->geometry_library()); + kernel->logger().Error("UNS", 2, "No support (after considering item upgrade) for " + ifcopenshell::geometry::taxonomy::kind_to_string(item->kind()) + created_from + " in kernel " + kernel->geometry_library()); return false; } }; @@ -214,7 +217,7 @@ namespace { template struct dispatch_curve_creation { static bool dispatch(const ifcopenshell::geometry::taxonomy::ptr& item, T&) { - Logger::Error("GEO", 28, "No conversion for " + std::to_string(item->kind())); + Logger::Root().Error("GEO", 28, "No conversion for " + std::to_string(item->kind())); return false; } }; @@ -236,10 +239,10 @@ namespace { template struct dispatch_surface_creation { static bool dispatch(const ifcopenshell::geometry::taxonomy::ptr& item, T&) { - Logger::Error("GEO", 29, "No conversion for " + std::to_string(item->kind())); + Logger::Root().Error("GEO", 29, "No conversion for " + std::to_string(item->kind())); return false; } }; } -#endif \ No newline at end of file +#endif diff --git a/src/ifcgeom/ConversionResult.cpp b/src/ifcgeom/ConversionResult.cpp index 7e6360e927..3924c5cb04 100644 --- a/src/ifcgeom/ConversionResult.cpp +++ b/src/ifcgeom/ConversionResult.cpp @@ -3,11 +3,11 @@ #include -IfcGeom::Representation::Triangulation * IfcGeom::ConversionResultShape::Triangulate(const ifcopenshell::geometry::Settings& settings) const +IfcGeom::Representation::Triangulation* IfcGeom::ConversionResultShape::Triangulate(const ifcopenshell::geometry::Settings& settings, Logger& logger) const { auto t = IfcGeom::Representation::Triangulation::empty(settings); static ifcopenshell::geometry::taxonomy::matrix4 iden; - Triangulate(settings, iden, t, -1, -1); + Triangulate(settings, iden, t, -1, -1, logger); return t; } diff --git a/src/ifcgeom/ConversionResult.h b/src/ifcgeom/ConversionResult.h index 43b25669a2..058fe8f867 100644 --- a/src/ifcgeom/ConversionResult.h +++ b/src/ifcgeom/ConversionResult.h @@ -253,8 +253,8 @@ namespace IfcGeom { class IFC_GEOM_API ConversionResultShape { public: - virtual void Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, Representation::Triangulation* t, int item_id, int surface_style_id) const = 0; - IfcGeom::Representation::Triangulation* Triangulate(const ifcopenshell::geometry::Settings& settings) const; + virtual void Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, Representation::Triangulation* t, int item_id, int surface_style_id, Logger& logger = Logger::Root()) const = 0; + IfcGeom::Representation::Triangulation* Triangulate(const ifcopenshell::geometry::Settings& settings, Logger& logger = Logger::Root()) const; virtual void Serialize(const ifcopenshell::geometry::taxonomy::matrix4& place, std::string&) const = 0; virtual int surface_genus() const = 0; diff --git a/src/ifcgeom/Converter.cpp b/src/ifcgeom/Converter.cpp index a534ffc084..15a4584088 100644 --- a/src/ifcgeom/Converter.cpp +++ b/src/ifcgeom/Converter.cpp @@ -4,10 +4,11 @@ using namespace ifcopenshell::geometry; -ifcopenshell::geometry::Converter::Converter(std::unique_ptr&& geometry_library, IfcParse::IfcFile* file, ifcopenshell::geometry::Settings& s) +ifcopenshell::geometry::Converter::Converter(std::unique_ptr&& geometry_library, IfcParse::IfcFile* file, ifcopenshell::geometry::Settings& s, Logger& logger) : kernel_(std::move(geometry_library)) + , logger_(logger) { - mapping_ = impl::mapping_implementations().construct(file, s); + mapping_ = impl::mapping_implementations().construct(file, s, logger_); // Mapping reads unit information and applies to settings settings_ = mapping_->settings(); } @@ -17,7 +18,7 @@ ifcopenshell::geometry::Converter::~Converter() { } namespace { - void substitute_with_box_based_on_density(IfcGeom::ConversionResults& items, double& density) { + void substitute_with_box_based_on_density(Logger& logger, IfcGeom::ConversionResults& items, double& density) { int nv = 0; void* box = nullptr; double volume = 0.; @@ -29,7 +30,7 @@ namespace { if (density > 1e5) { items[0].Shape()->set_box(box); items.erase(items.begin() + 1, items.end()); - Logger::Notice("GEO", 30, "Substituted element with " + boost::lexical_cast(density) + " vertices / m3 with a bounding box"); + logger.Notice("GEO", 30, "Substituted element with " + boost::lexical_cast(density) + " vertices / m3 with a bounding box"); } } } @@ -138,7 +139,7 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe } } if (some_items_without_style) { - Logger::Warning("GEO", 31, "No material and surface styles for:", product); + logger_.Warning("GEO", 31, "No material and surface styles for:", product); } } @@ -162,7 +163,7 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe parent_id = parent_object->id(); } } catch (const std::exception& e) { - Logger::Error("GEO", 32, e); + logger_.Error("GEO", 32, e); } const std::string name = product->get_value("Name", ""); @@ -208,10 +209,10 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe kernel_->convert_openings(product, opening_items, shapes, *place, opened_shapes); } } catch (const std::exception& e) { - Logger::Message(Logger::LOG_ERROR, "GEO", 33, std::string("Error processing openings for: ") + e.what() + ":", product); + logger_.Message(Logger::LOG_ERROR, "GEO", 33, std::string("Error processing openings for: ") + e.what() + ":", product); caught_error = true; } catch (...) { - Logger::Message(Logger::LOG_ERROR, "GEO", 34, "Error processing openings for:", product); + logger_.Message(Logger::LOG_ERROR, "GEO", 34, "Error processing openings for:", product); } if (!(caught_error && opened_shapes.size() < shapes.size())) { @@ -239,7 +240,7 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe std::swap(shapes, unified_shapes); } } catch (std::exception& e) { - Logger::Error("GEO", 35, e); + logger_.Error("GEO", 35, e); } } @@ -357,7 +358,7 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_process parent_id = parent_object->id(); } } catch (const std::exception& e) { - Logger::Error("GEO", 36, e); + logger_.Error("GEO", 36, e); } const std::string guid = product->get_value("GlobalId"); diff --git a/src/ifcgeom/Converter.h b/src/ifcgeom/Converter.h index 9fff13df04..1addbfb3a3 100644 --- a/src/ifcgeom/Converter.h +++ b/src/ifcgeom/Converter.h @@ -21,15 +21,17 @@ namespace ifcopenshell { namespace geometry { std::unique_ptr kernel_; ifcopenshell::geometry::Settings settings_; std::map cache_; + Logger& logger_; public: ifcopenshell::geometry::kernels::AbstractKernel* kernel() { return &*kernel_; } - Converter(std::unique_ptr&& geometry_library, IfcParse::IfcFile* file, ifcopenshell::geometry::Settings& settings); + Converter(std::unique_ptr&& geometry_library, IfcParse::IfcFile* file, ifcopenshell::geometry::Settings& settings, Logger& logger = Logger::Root()); ~Converter(); ifcopenshell::geometry::abstract_mapping* mapping() const { return mapping_; } + Logger& logger() const { return logger_; } /* virtual NativeElement* convert( @@ -55,4 +57,4 @@ namespace ifcopenshell { namespace geometry { }; }} -#endif \ No newline at end of file +#endif diff --git a/src/ifcgeom/GeometrySerializer.h b/src/ifcgeom/GeometrySerializer.h index d8d4605de5..6a3ba7f095 100644 --- a/src/ifcgeom/GeometrySerializer.h +++ b/src/ifcgeom/GeometrySerializer.h @@ -143,8 +143,9 @@ class GeometrySerializer : public Serializer { public: enum read_type { READ_BREP, READ_TRIANGULATION }; - GeometrySerializer(const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings) - : geometry_settings_(geometry_settings) + GeometrySerializer(const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger& logger = Logger::Root()) + : Serializer(logger) + , geometry_settings_(geometry_settings) , settings_(settings) {} virtual ~GeometrySerializer() {} @@ -177,7 +178,7 @@ protected: class WriteOnlyGeometrySerializer : public GeometrySerializer { public: - WriteOnlyGeometrySerializer(const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings) : GeometrySerializer(geometry_settings, settings) {} + WriteOnlyGeometrySerializer(const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger& logger = Logger::Root()) : GeometrySerializer(geometry_settings, settings, logger) {} virtual IfcGeom::Element* read(IfcParse::IfcFile&, const std::string&, const std::string&, read_type = READ_BREP) { throw std::runtime_error("Not supported"); diff --git a/src/ifcgeom/IfcGeomElement.h b/src/ifcgeom/IfcGeomElement.h index 2b16dacd1f..fe0e92dd0d 100644 --- a/src/ifcgeom/IfcGeomElement.h +++ b/src/ifcgeom/IfcGeomElement.h @@ -125,7 +125,7 @@ namespace IfcGeom { oss << "product-" << IfcParse::IfcGlobalId(guid).formatted(); } catch (const std::exception& e) { oss << "product"; - Logger::Error("GEO", 39, e); + Logger::Root().Error("GEO", 39, e); } } diff --git a/src/ifcgeom/Iterator.cpp b/src/ifcgeom/Iterator.cpp index e0213bb430..c55a4ee95b 100644 --- a/src/ifcgeom/Iterator.cpp +++ b/src/ifcgeom/Iterator.cpp @@ -31,7 +31,7 @@ bool IfcGeom::Iterator::initialize() { try { converter_->mapping()->get_representations(reps, filters_); } catch (const std::exception& e) { - Logger::Error("GEO", 50, e); + logger_.Error("GEO", 50, e); } time_points[1] = high_resolution_clock::now(); @@ -94,7 +94,7 @@ bool IfcGeom::Iterator::initialize() { tasks_.back().item = p.first; tasks_.back().products = p.second; } - Logger::Notice("SYS", 26, "Merged " + std::to_string(old_size) + " tasks into " + std::to_string(tasks_.size()) + " tasks due to permissive shape reuse"); + logger_.Notice("SYS", 26, "Merged " + std::to_string(old_size) + " tasks into " + std::to_string(tasks_.size()) + " tasks due to permissive shape reuse"); } } @@ -139,10 +139,10 @@ bool IfcGeom::Iterator::initialize() { } */ - Logger::Notice("SYS", 27, "Created " + boost::lexical_cast(tasks_.size()) + " tasks for " + boost::lexical_cast(num_products) + " products"); + logger_.Notice("SYS", 27, "Created " + boost::lexical_cast(tasks_.size()) + " tasks for " + boost::lexical_cast(num_products) + " products"); if (tasks_.size() == 0) { - Logger::Warning("GEO", 51, "No representations encountered, aborting"); + logger_.Warning("GEO", 51, "No representations encountered, aborting"); initialization_outcome_.reset(false); } else if (!settings_.get().get()) { @@ -194,7 +194,7 @@ void IfcGeom::Iterator::process_concurrently() { kernel_pool.reserve(conc_threads); for (unsigned i = 0; i < conc_threads; ++i) { - kernel_pool.push_back(new ifcopenshell::geometry::Converter(std::unique_ptr(converter_->kernel()->clone()), ifc_file, settings_)); + kernel_pool.push_back(new ifcopenshell::geometry::Converter(std::unique_ptr(converter_->kernel()->clone()), ifc_file, settings_, logger_)); } std::vector> threadpool; @@ -231,14 +231,14 @@ void IfcGeom::Iterator::process_concurrently() { try { this->create_element_(kernel, settings, rep); } catch (const std::exception& e) { - Logger::Error("GEO", 52, + logger_.Error("GEO", 52, std::string("Exception '") + e.what() + std::string("' occurred while iterator was creating a shape: "), rep->item->instance ); had_error_processing_elements_ = true; } catch (...) { - Logger::Error("GEO", 53, + logger_.Error("GEO", 53, "Unknown exception occurred while iteartor was creating a shape: ", rep->item->instance ); @@ -263,10 +263,10 @@ void IfcGeom::Iterator::process_concurrently() { finished_ = true; - Logger::SetProduct(boost::none); + logger_.SetProduct(boost::none); if (!terminating_) { - Logger::Status("\rDone creating geometry (" + boost::lexical_cast(all_processed_elements_.size()) + + logger_.Status("\rDone creating geometry (" + boost::lexical_cast(all_processed_elements_.size()) + " objects) "); } } @@ -360,20 +360,20 @@ void IfcGeom::Iterator::create_element_(ifcopenshell::geometry::Converter* kerne const IfcUtil::IfcBaseEntity* product = product_node.first; const auto& place = product_node.second; - Logger::SetProduct(product); + logger_.SetProduct(product); IfcGeom::BRepElement* brep = static_cast(decorate_with_cache_(GeometrySerializer::READ_BREP, (std::string)product->get("GlobalId"), std::to_string(rep->item->instance->as()->id()), [kernel, settings, product, place, rep]() { return kernel->create_brep_for_representation_and_product(rep->item, product, place); })); if (!brep) { - Logger::SetProduct(boost::none); + logger_.SetProduct(boost::none); return; } auto elem = process_based_on_settings(settings, brep); if (!elem) { - Logger::SetProduct(boost::none); + logger_.SetProduct(boost::none); return; } @@ -397,7 +397,7 @@ void IfcGeom::Iterator::create_element_(ifcopenshell::geometry::Converter* kerne } } - Logger::SetProduct(boost::none); + logger_.SetProduct(boost::none); } IfcGeom::Element* IfcGeom::Iterator::process_based_on_settings(ifcopenshell::geometry::Settings settings, IfcGeom::BRepElement* elem, IfcGeom::TriangulationElement* previous) @@ -406,7 +406,7 @@ IfcGeom::Element* IfcGeom::Iterator::process_based_on_settings(ifcopenshell::geo try { return new IfcGeom::SerializedElement(*elem); } catch (...) { - Logger::Message(Logger::LOG_ERROR, "GEO", 54, "Getting a serialized element from model failed."); + logger_.Message(Logger::LOG_ERROR, "GEO", 54, "Getting a serialized element from model failed."); return nullptr; } } else if (settings.get().get() == ifcopenshell::geometry::settings::TRIANGULATED) { @@ -417,7 +417,7 @@ IfcGeom::Element* IfcGeom::Iterator::process_based_on_settings(ifcopenshell::geo gid2 = gid2.substr(0, hyphen); } - return decorate_with_cache_(GeometrySerializer::READ_TRIANGULATION, elem->guid(), gid2, [elem, previous]() { + return decorate_with_cache_(GeometrySerializer::READ_TRIANGULATION, elem->guid(), gid2, [this, elem, previous]() { try { if (!previous) { return new TriangulationElement(*elem); @@ -425,7 +425,7 @@ IfcGeom::Element* IfcGeom::Iterator::process_based_on_settings(ifcopenshell::geo return new TriangulationElement(*elem, previous->geometry_pointer()); } } catch (...) { - Logger::Message(Logger::LOG_ERROR, "GEO", 55, "Getting a triangulation element from model failed."); + logger_.Message(Logger::LOG_ERROR, "GEO", 55, "Getting a triangulation element from model failed."); } return (TriangulationElement*)nullptr; }); @@ -466,7 +466,7 @@ void IfcGeom::Iterator::log_timepoints() const { for (auto it = time_points.begin() + 1; it != time_points.end(); ++it) { auto jt = it - 1; duration ms_double = (*it) - (*jt); - Logger::Notice("SYS", 28, labels[std::distance(time_points.begin(), jt)] + " took " + std::to_string(ms_double.count()) + "ms"); + logger_.Notice("SYS", 28, labels[std::distance(time_points.begin(), jt)] + " took " + std::to_string(ms_double.count()) + "ms"); } } @@ -501,7 +501,7 @@ const IfcUtil::IfcBaseClass* IfcGeom::Iterator::next() { if (num_threads_ != 1) { if (!wait_for_element()) { - Logger::SetProduct(boost::none); + logger_.SetProduct(boost::none); time_points[3] = high_resolution_clock::now(); log_timepoints(); task_result_ptr_exhausted = true; @@ -517,7 +517,7 @@ const IfcUtil::IfcBaseClass* IfcGeom::Iterator::next() { // shape representation if (task_result_iterator_ == --all_processed_elements_.end()) { if (!create()) { - Logger::SetProduct(boost::none); + logger_.SetProduct(boost::none); time_points[3] = high_resolution_clock::now(); log_timepoints(); task_result_ptr_exhausted = true; @@ -554,7 +554,7 @@ IfcGeom::Element* IfcGeom::Iterator::get() try { parent_object = get_object(ret->parent_id()); } catch (const std::exception& e) { - Logger::Error("GEO", 56, e); + logger_.Error("GEO", 56, e); hasParent = false; } @@ -572,7 +572,7 @@ IfcGeom::Element* IfcGeom::Iterator::get() try { parent_object = get_object(pid); } catch (const std::exception& e) { - Logger::Error("GEO", 57, e); + logger_.Error("GEO", 57, e); hasParent = false; } } @@ -619,9 +619,9 @@ const IfcGeom::Element* IfcGeom::Iterator::get_object(int id) { m4 = casted->matrix; } } catch (const std::exception& e) { - Logger::Error("GEO", 58, e); + logger_.Error("GEO", 58, e); } catch (...) { - Logger::Error("GEO", 59, "Unknown error returning product"); + logger_.Error("GEO", 59, "Unknown error returning product"); } Element* ifc_object = new Element(settings_, id, parent_id, product_name, instance_type, product_guid, "", m4, ifc_product); @@ -633,10 +633,10 @@ const IfcUtil::IfcBaseClass* IfcGeom::Iterator::create() { try { product = create_shape_model_for_next_entity(); } catch (const std::exception& e) { - Logger::Error("GEO", 60, e); + logger_.Error("GEO", 60, e); had_error_processing_elements_ = true; } catch (...) { - Logger::Error("GEO", 61, "Unknown error creating geometry"); + logger_.Error("GEO", 61, "Unknown error creating geometry"); had_error_processing_elements_ = true; } return product; @@ -808,8 +808,8 @@ ifcopenshell::geometry::taxonomy::direction3::ptr IfcGeom::Iterator::remove_offs } } - Logger::Notice("SYS", 29, "Removed large offsets within " + std::to_string(num_offset_applied) + " products"); - Logger::Notice("SYS", 30, "Offset applied (" + std::to_string(vec(0)) + "," + std::to_string(vec(1)) + "," + std::to_string(vec(2)) + ")"); + logger_.Notice("SYS", 29, "Removed large offsets within " + std::to_string(num_offset_applied) + " products"); + logger_.Notice("SYS", 30, "Offset applied (" + std::to_string(vec(0)) + "," + std::to_string(vec(1)) + "," + std::to_string(vec(2)) + ")"); return make(vec); } diff --git a/src/ifcgeom/Iterator.h b/src/ifcgeom/Iterator.h index fc9e542d60..a10021b943 100644 --- a/src/ifcgeom/Iterator.h +++ b/src/ifcgeom/Iterator.h @@ -126,6 +126,7 @@ namespace IfcGeom { std::vector filters_; int num_threads_; std::string geometry_library_; + Logger& logger_; // When single-threaded ifcopenshell::geometry::Converter* converter_; @@ -209,32 +210,35 @@ namespace IfcGeom { ifcopenshell::geometry::taxonomy::direction3::ptr remove_offset_(); public: - Iterator(std::unique_ptr&& geometry_library, const ifcopenshell::geometry::Settings& settings, IfcParse::IfcFile* file, const std::vector& filters, int num_threads) + Iterator(std::unique_ptr&& geometry_library, const ifcopenshell::geometry::Settings& settings, IfcParse::IfcFile* file, const std::vector& filters, int num_threads, Logger& logger = Logger::Root()) : settings_(settings) , ifc_file(file) , filters_(filters) , num_threads_(num_threads) , geometry_library_(geometry_library->geometry_library()) + , logger_(logger) // @todo verify whether settings are correctly passed on - , converter_(new ifcopenshell::geometry::Converter(std::move(geometry_library), ifc_file, settings_)) + , converter_(new ifcopenshell::geometry::Converter(std::move(geometry_library), ifc_file, settings_, logger_)) { } - Iterator(std::unique_ptr&& geometry_library, const ifcopenshell::geometry::Settings& settings, IfcParse::IfcFile* file) + Iterator(std::unique_ptr&& geometry_library, const ifcopenshell::geometry::Settings& settings, IfcParse::IfcFile* file, Logger& logger = Logger::Root()) : settings_(settings) , ifc_file(file) , num_threads_(1) , geometry_library_(geometry_library->geometry_library()) - , converter_(new ifcopenshell::geometry::Converter(std::move(geometry_library), ifc_file, settings_)) + , logger_(logger) + , converter_(new ifcopenshell::geometry::Converter(std::move(geometry_library), ifc_file, settings_, logger_)) { } - Iterator(std::unique_ptr&& geometry_library, const ifcopenshell::geometry::Settings& settings, IfcParse::IfcFile* file, int num_threads) + Iterator(std::unique_ptr&& geometry_library, const ifcopenshell::geometry::Settings& settings, IfcParse::IfcFile* file, int num_threads, Logger& logger = Logger::Root()) : settings_(settings) , ifc_file(file) , num_threads_(num_threads) , geometry_library_(geometry_library->geometry_library()) - , converter_(new ifcopenshell::geometry::Converter(std::move(geometry_library), ifc_file, settings_)) + , logger_(logger) + , converter_(new ifcopenshell::geometry::Converter(std::move(geometry_library), ifc_file, settings_, logger_)) { } @@ -301,7 +305,7 @@ namespace IfcGeom { return progress_; } - std::string getLog() const { return Logger::GetLog(); } + std::string getLog() const { return logger_.GetLog(); } IfcParse::IfcFile* file() const { return ifc_file; } diff --git a/src/ifcgeom/Serializer.h b/src/ifcgeom/Serializer.h index ba5d6fab69..83d089faef 100644 --- a/src/ifcgeom/Serializer.h +++ b/src/ifcgeom/Serializer.h @@ -21,15 +21,22 @@ #define SERIALIZER_H #include "../ifcparse/IfcFile.h" +#include "../ifcparse/IfcLogger.h" class Serializer { +protected: + Logger& logger_; + public: + explicit Serializer(Logger& logger = Logger::Root()) : logger_(logger) {} virtual ~Serializer() {} + Logger& logger() const { return logger_; } + virtual bool ready() = 0; virtual void writeHeader() = 0; virtual void finalize() = 0; virtual void setFile(IfcParse::IfcFile*) = 0; }; -#endif \ No newline at end of file +#endif diff --git a/src/ifcgeom/abstract_mapping.cpp b/src/ifcgeom/abstract_mapping.cpp index fd253edc5d..44cbd7d0b5 100644 --- a/src/ifcgeom/abstract_mapping.cpp +++ b/src/ifcgeom/abstract_mapping.cpp @@ -37,14 +37,14 @@ void ifcopenshell::geometry::impl::MappingFactoryImplementation::bind(const std: this->insert(std::make_pair(schema_name_lower, fn)); } -ifcopenshell::geometry::abstract_mapping* ifcopenshell::geometry::impl::MappingFactoryImplementation::construct(IfcParse::IfcFile* file, Settings& s) { +ifcopenshell::geometry::abstract_mapping* ifcopenshell::geometry::impl::MappingFactoryImplementation::construct(IfcParse::IfcFile* file, Settings& s, Logger& logger) { const std::string schema_name_lower = boost::to_lower_copy(file->schema()->name()); std::map::const_iterator it; it = this->find(schema_name_lower); if (it == end()) { throw IfcParse::IfcException("No geometry mapping registered for " + schema_name_lower); } - auto new_mapping = it->second(file, s); + auto new_mapping = it->second(file, s, logger); new_mapping->initialize_settings(); return new_mapping; } diff --git a/src/ifcgeom/abstract_mapping.h b/src/ifcgeom/abstract_mapping.h index 6d47b32829..57d0f8dae5 100644 --- a/src/ifcgeom/abstract_mapping.h +++ b/src/ifcgeom/abstract_mapping.h @@ -21,6 +21,7 @@ #define ABSTRACT_MAPPING_H #include "../ifcparse/IfcBaseClass.h" +#include "../ifcparse/IfcLogger.h" #include "../ifcparse/aggregate_of_instance.h" #include "../ifcgeom/taxonomy.h" #include "../ifcgeom/ConversionSettings.h" @@ -43,14 +44,15 @@ namespace geometry { typedef boost::function filter_t; - class IFC_GEOM_API abstract_mapping { + class IFC_GEOM_API abstract_mapping { protected: Settings settings_; + Logger& logger_; bool use_caching_ = true; public: - abstract_mapping(Settings& s) : settings_(s) {} + abstract_mapping(Settings& s, Logger& logger = Logger::Root()) : settings_(s), logger_(logger) {} virtual ~abstract_mapping() {} virtual ifcopenshell::geometry::taxonomy::ptr map(const IfcUtil::IfcBaseInterface*) = 0; @@ -69,19 +71,20 @@ namespace geometry { const Settings& settings() const { return settings_; } Settings& settings() { return settings_; } + Logger& logger() const { return logger_; } bool use_caching() const { return use_caching_; } bool& use_caching() { return use_caching_; } }; namespace impl { - typedef boost::function2 mapping_fn; + typedef boost::function3 mapping_fn; class IFC_GEOM_API MappingFactoryImplementation : public std::map { public: MappingFactoryImplementation(); void bind(const std::string& schema_name, mapping_fn); - abstract_mapping* construct(IfcParse::IfcFile*, Settings&); + abstract_mapping* construct(IfcParse::IfcFile*, Settings&, Logger& logger = Logger::Root()); }; IFC_GEOM_API MappingFactoryImplementation& mapping_implementations(); diff --git a/src/ifcgeom/function_item_evaluator.cpp b/src/ifcgeom/function_item_evaluator.cpp index c96a3cefc9..72af7e0ef7 100644 --- a/src/ifcgeom/function_item_evaluator.cpp +++ b/src/ifcgeom/function_item_evaluator.cpp @@ -76,7 +76,7 @@ struct piecewise_fn_evaluator : public fn_evaluator { span_start += fn->length(); } - Logger::Error("GEO", 37, "piecewise span not found."); + logger_.Error("GEO", 37, "piecewise span not found."); return {0, 0, nullptr}; } @@ -208,7 +208,7 @@ struct offset_fn_evaluator : public fn_evaluator { -function_item_evaluator::function_item_evaluator(const ifcopenshell::geometry::Settings& settings,taxonomy::function_item::const_ptr fn) { +function_item_evaluator::function_item_evaluator(const ifcopenshell::geometry::Settings& settings,taxonomy::function_item::const_ptr fn, Logger& logger) : logger_(logger) { auto kind = fn->kind(); if (kind == taxonomy::FUNCTOR_ITEM) { fn_evaluator_ = new functor_fn_evaluator(std::dynamic_pointer_cast(fn),settings); @@ -221,11 +221,11 @@ function_item_evaluator::function_item_evaluator(const ifcopenshell::geometry::S } else if (kind == taxonomy::OFFSET_FUNCTION) { fn_evaluator_ = new offset_fn_evaluator(std::dynamic_pointer_cast(fn), settings); } else { - Logger::Error("GEO", 38, "Unexpected function type"); + logger_.Error("GEO", 38, "Unexpected function type"); } } -function_item_evaluator::function_item_evaluator(const function_item_evaluator& other) { +function_item_evaluator::function_item_evaluator(const function_item_evaluator& other) : logger_(other.logger_) { fn_evaluator_ = other.fn_evaluator_->clone(); eval_points_ = other.eval_points_; } diff --git a/src/ifcgeom/function_item_evaluator.h b/src/ifcgeom/function_item_evaluator.h index 9773c8731c..07c60ff518 100644 --- a/src/ifcgeom/function_item_evaluator.h +++ b/src/ifcgeom/function_item_evaluator.h @@ -23,7 +23,7 @@ static taxonomy::function_item::ptr convert_loop_to_function_item(taxonomy::loop /// @brief Abstract class for evaluating a function_item. This class is specialized for each of the function_item types. struct IFC_GEOM_API fn_evaluator { - fn_evaluator(const ifcopenshell::geometry::Settings& settings) : settings_(settings) { + fn_evaluator(const ifcopenshell::geometry::Settings& settings, Logger& logger = Logger::Root()) : settings_(settings), logger_(logger) { } fn_evaluator(const fn_evaluator& other) = default; virtual ~fn_evaluator() = default; @@ -36,12 +36,15 @@ struct IFC_GEOM_API fn_evaluator { double length() const { return end() - start(); } ifcopenshell::geometry::Settings settings_; + + protected: + Logger& logger_; }; /// @brief utility class to evaluate function_item objects. class IFC_GEOM_API function_item_evaluator { public: - function_item_evaluator(const ifcopenshell::geometry::Settings& settings, taxonomy::function_item::const_ptr fn); + function_item_evaluator(const ifcopenshell::geometry::Settings& settings, taxonomy::function_item::const_ptr fn, Logger& logger = Logger::Root()); function_item_evaluator(const function_item_evaluator& other); ~function_item_evaluator(); @@ -77,6 +80,7 @@ class IFC_GEOM_API function_item_evaluator { fn_evaluator* fn_evaluator_ = nullptr; mutable boost::optional> eval_points_; // cache evaluation points + Logger& logger_; }; }} diff --git a/src/ifcgeom/hybrid_kernel.h b/src/ifcgeom/hybrid_kernel.h index dfe7cd200d..5f8a672261 100644 --- a/src/ifcgeom/hybrid_kernel.h +++ b/src/ifcgeom/hybrid_kernel.h @@ -64,10 +64,10 @@ namespace ifcopenshell { ifcopenshell::geometry::abstract_mapping* mapping_; IfcParse::IfcFile* file_; public: - HybridKernel(const std::string& name, IfcParse::IfcFile* file, Settings& settings, std::vector>&& kernels) - : AbstractKernel(name, settings) + HybridKernel(const std::string& name, IfcParse::IfcFile* file, Settings& settings, std::vector>&& kernels, Logger& logger = Logger::Root()) + : AbstractKernel(name, settings, logger) , kernels_(std::move(kernels)) - , mapping_(ifcopenshell::geometry::impl::mapping_implementations().construct(file, settings)) + , mapping_(ifcopenshell::geometry::impl::mapping_implementations().construct(file, settings, logger)) , file_(file) { } @@ -163,26 +163,26 @@ namespace ifcopenshell { ks.emplace_back(k->clone()); } // @todo ugly - return new HybridKernel(geometry_library(), file_, const_cast(settings()), std::move(ks)); + return new HybridKernel(geometry_library(), file_, const_cast(settings()), std::move(ks), logger()); } }; - inline std::unique_ptr construct(IfcParse::IfcFile* file, const std::string& geometry_library, Settings& conv_settings) { + inline std::unique_ptr construct(IfcParse::IfcFile* file, const std::string& geometry_library, Settings& conv_settings, Logger& logger = Logger::Root()) { std::string geometry_library_lower = boost::to_lower_copy(geometry_library); #ifdef IFOPSH_WITH_OPENCASCADE if (geometry_library_lower == "opencascade") { - return std::make_unique(conv_settings); + return std::make_unique(conv_settings, logger); } #endif #ifdef IFOPSH_WITH_CGAL if (geometry_library_lower == "cgal") { - return std::make_unique(conv_settings); + return std::make_unique(conv_settings, logger); } if (geometry_library_lower == "cgal-simple") { - return std::make_unique(conv_settings); + return std::make_unique(conv_settings, logger); } #endif @@ -198,19 +198,19 @@ namespace ifcopenshell { auto n = kernels.size(); #ifdef IFOPSH_WITH_OPENCASCADE if (geometry_library_lower.find("opencascade", 0) == 0) { - kernels.emplace_back(new IfcGeom::OpenCascadeKernel(conv_settings)); + kernels.emplace_back(new IfcGeom::OpenCascadeKernel(conv_settings, logger)); geometry_library_lower = geometry_library_lower.substr(strlen("opencascade")); } #endif #ifdef IFOPSH_WITH_CGAL if (geometry_library_lower.find("cgal-simple", 0) == 0) { - kernels.emplace_back(new SimpleCgalKernel(conv_settings)); + kernels.emplace_back(new SimpleCgalKernel(conv_settings, logger)); geometry_library_lower = geometry_library_lower.substr(strlen("cgal-simple")); } if (geometry_library_lower.find("cgal", 0) == 0) { - kernels.emplace_back(new CgalKernel(conv_settings)); + kernels.emplace_back(new CgalKernel(conv_settings, logger)); geometry_library_lower = geometry_library_lower.substr(strlen("cgal")); } #endif @@ -225,7 +225,7 @@ namespace ifcopenshell { } if (!kernels.empty()) { - return std::make_unique(geometry_library, file, conv_settings, std::move(kernels)); + return std::make_unique(geometry_library, file, conv_settings, std::move(kernels), logger); } } @@ -236,4 +236,4 @@ namespace ifcopenshell { } } -#endif \ No newline at end of file +#endif diff --git a/src/ifcgeom/infra_sweep_helper.cpp b/src/ifcgeom/infra_sweep_helper.cpp index 6b092c3e64..b8f473bf4b 100644 --- a/src/ifcgeom/infra_sweep_helper.cpp +++ b/src/ifcgeom/infra_sweep_helper.cpp @@ -35,7 +35,7 @@ bool has_intersection(const std::set& A, } -taxonomy::loft::ptr ifcopenshell::geometry::make_loft(const Settings& settings_, const IfcUtil::IfcBaseClass* inst, const taxonomy::function_item::ptr& fn, std::vector& cross_sections) +taxonomy::loft::ptr ifcopenshell::geometry::make_loft(const Settings& settings_, const IfcUtil::IfcBaseClass* inst, const taxonomy::function_item::ptr& fn, std::vector& cross_sections, Logger& logger) { std::sort(cross_sections.begin(), cross_sections.end()); @@ -51,7 +51,7 @@ taxonomy::loft::ptr ifcopenshell::geometry::make_loft(const Settings& settings_, double end = std::min(fn->length(), cross_sections.back().dist_along); if (end - start < 1.e-9) { - Logger::Warning("GEO", 40, "Empty sweep domain with start at " + std::to_string(cross_sections.front().dist_along) + " end at " + std::to_string(cross_sections.back().dist_along) + " and curve domain length " + std::to_string(fn->length()), inst); + Logger::Root().Warning("GEO", 40, "Empty sweep domain with start at " + std::to_string(cross_sections.front().dist_along) + " end at " + std::to_string(cross_sections.back().dist_along) + " and curve domain length " + std::to_string(fn->length()), inst); return nullptr; } @@ -130,7 +130,7 @@ taxonomy::loft::ptr ifcopenshell::geometry::make_loft(const Settings& settings_, auto profile_b_f = std::static_pointer_cast(profile_b); if (profile_a_f->children.size() != profile_b_f->children.size()) { - Logger::Warning("GEO", 41, "Mismatching number of face boundaries: " + + Logger::Root().Warning("GEO", 41, "Mismatching number of face boundaries: " + std::to_string(profile_a_f->children.size()) + " vs " + std::to_string(profile_b_f->children.size()), inst @@ -165,7 +165,7 @@ taxonomy::loft::ptr ifcopenshell::geometry::make_loft(const Settings& settings_, // in which case we would need to lerp with the rotation component below in m4b. interpolated_rotation = lerp(*rotation_a, *rotation_b, relative_dist_along); } else if (rotation_a != rotation_b) { - Logger::Error("GEO", 42, "Direction vectors on cross section placements only supported when used consistently"); + logger.Error("GEO", 42, "Direction vectors on cross section placements only supported when used consistently"); } taxonomy::loop::ptr w1, w2; @@ -176,12 +176,12 @@ taxonomy::loft::ptr ifcopenshell::geometry::make_loft(const Settings& settings_, boost::tie(w1, w2) = tmp_; if (w1->closed != w2->closed) { - Logger::Warning("GEO", 43, "Mismatching closed property on loops", inst); + logger.Warning("GEO", 43, "Mismatching closed property on loops", inst); return nullptr; } if (w1->tags.is_initialized() != w2->tags.is_initialized()) { - Logger::Warning("GEO", 44, "Mismatching availability tags on loops", inst); + logger.Warning("GEO", 44, "Mismatching availability tags on loops", inst); return nullptr; } @@ -190,7 +190,7 @@ taxonomy::loft::ptr ifcopenshell::geometry::make_loft(const Settings& settings_, std::set tags_seen; for (const auto& t : *w1->tags) { if (tags_seen.find(t) != tags_seen.end()) { - Logger::Warning("GEO", 45, "Duplicate tag '" + t + "' on loft profile", inst); + logger.Warning("GEO", 45, "Duplicate tag '" + t + "' on loft profile", inst); return nullptr; } tags_seen.insert(t); @@ -202,7 +202,7 @@ taxonomy::loft::ptr ifcopenshell::geometry::make_loft(const Settings& settings_, std::set tags_seen; for (const auto& t : *w2->tags) { if (tags_seen.find(t) != tags_seen.end()) { - Logger::Warning("GEO", 46, "Duplicate tag '" + t + "' on loft profile", inst); + logger.Warning("GEO", 46, "Duplicate tag '" + t + "' on loft profile", inst); return nullptr; } tags_seen.insert(t); @@ -303,20 +303,20 @@ taxonomy::loft::ptr ifcopenshell::geometry::make_loft(const Settings& settings_, for (auto& p1_tags : w1_tags) { if (!has_intersection(p1_tags, w2_tags_combined)) { - Logger::Warning("GEO", 47, "No matching tags found on loft profiles: " + join_tags(p1_tags) + " not in " + join_tags(w2_tags_combined), inst); + logger.Warning("GEO", 47, "No matching tags found on loft profiles: " + join_tags(p1_tags) + " not in " + join_tags(w2_tags_combined), inst); return nullptr; } } for (auto& p2_tags : w2_tags) { if (!has_intersection(p2_tags, w1_tags_combined)) { - Logger::Warning("GEO", 48, "No matching tags found on loft profiles: " + join_tags(p2_tags) + " not in " + join_tags(w1_tags_combined), inst); + logger.Warning("GEO", 48, "No matching tags found on loft profiles: " + join_tags(p2_tags) + " not in " + join_tags(w1_tags_combined), inst); return nullptr; } } } else { if (w1->children.size() != w2->children.size()) { - Logger::Warning("GEO", 49, "Mismatching number of edges: " + + logger.Warning("GEO", 49, "Mismatching number of edges: " + std::to_string(w1->children.size()) + " vs " + std::to_string(w2->children.size()), inst); diff --git a/src/ifcgeom/infra_sweep_helper.h b/src/ifcgeom/infra_sweep_helper.h index a14d655094..73cae86d78 100644 --- a/src/ifcgeom/infra_sweep_helper.h +++ b/src/ifcgeom/infra_sweep_helper.h @@ -21,7 +21,7 @@ namespace ifcopenshell { } }; - IFC_GEOM_API taxonomy::loft::ptr make_loft(const Settings& settings_, const IfcUtil::IfcBaseClass* inst, const taxonomy::function_item::ptr& directrix, std::vector& cross_sections); + IFC_GEOM_API taxonomy::loft::ptr make_loft(const Settings& settings_, const IfcUtil::IfcBaseClass* inst, const taxonomy::function_item::ptr& directrix, std::vector& cross_sections, Logger& logger = Logger::Root()); } } diff --git a/src/ifcgeom/kernels/cgal/CgalConversionResult.cpp b/src/ifcgeom/kernels/cgal/CgalConversionResult.cpp index 5036335b9b..fc3e642b6c 100644 --- a/src/ifcgeom/kernels/cgal/CgalConversionResult.cpp +++ b/src/ifcgeom/kernels/cgal/CgalConversionResult.cpp @@ -99,7 +99,7 @@ namespace { } } -ifcopenshell::geometry::CgalShape::CgalShape(const cgal_shape_t& shape, bool convex) { +ifcopenshell::geometry::CgalShape::CgalShape(const cgal_shape_t& shape, bool convex, Logger& logger) { shape_ = shape; convex_tag_ = convex; @@ -112,7 +112,7 @@ ifcopenshell::geometry::CgalShape::CgalShape(const cgal_shape_t& shape, bool con auto b2 = plane.base2(); if (V.squared_length() == 0) { - Logger::Warning("GEO", 62, "Removed face due to self-intersections"); + logger.Warning("GEO", 62, "Removed face due to self-intersections"); faces_to_remove.insert(face); continue; } @@ -133,7 +133,7 @@ ifcopenshell::geometry::CgalShape::CgalShape(const cgal_shape_t& shape, bool con } if (!CGAL::Polygon_2(ps.begin(), ps.end()).is_simple()) { - Logger::Warning("GEO", 63, "Removed face due to self-intersections"); + logger.Warning("GEO", 63, "Removed face due to self-intersections"); faces_to_remove.insert(face); } } @@ -184,7 +184,7 @@ void ifcopenshell::geometry::CgalShape::to_nef() const { } #endif -void ifcopenshell::geometry::CgalShape::Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int item_id, int surface_style_id) const { +void ifcopenshell::geometry::CgalShape::Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int item_id, int surface_style_id, Logger& logger) const { const bool all_triangles = std::all_of(shape_->facets_begin(), shape_->facets_end(), [](auto f) { return f.is_triangle(); }); const bool has_iden_transform = place.is_identity(); @@ -233,7 +233,7 @@ void ifcopenshell::geometry::CgalShape::Triangulate(ifcopenshell::geometry::Sett if (!all_triangles) { if (!shape_to_use->is_valid()) { - Logger::Message(Logger::LOG_ERROR, "GEO", 64, "Invalid Polyhedron_3 in object (before triangulation)"); + logger.Message(Logger::LOG_ERROR, "GEO", 64, "Invalid Polyhedron_3 in object (before triangulation)"); return; } @@ -241,19 +241,19 @@ void ifcopenshell::geometry::CgalShape::Triangulate(ifcopenshell::geometry::Sett try { success = CGAL::Polygon_mesh_processing::triangulate_faces(*shape_to_use); } catch (...) { - Logger::Message(Logger::LOG_ERROR, "GEO", 65, "Triangulation crashed"); + logger.Message(Logger::LOG_ERROR, "GEO", 65, "Triangulation crashed"); return; } CGAL::Polygon_mesh_processing::remove_degenerate_faces(*shape_to_use); if (!success) { - Logger::Message(Logger::LOG_ERROR, "GEO", 66, "Triangulation failed"); + logger.Message(Logger::LOG_ERROR, "GEO", 66, "Triangulation failed"); return; } if (!shape_to_use->is_valid()) { - Logger::Message(Logger::LOG_ERROR, "GEO", 67, "Invalid Polyhedron_3 in object (after triangulation)"); + logger.Message(Logger::LOG_ERROR, "GEO", 67, "Invalid Polyhedron_3 in object (after triangulation)"); return; } } @@ -282,7 +282,7 @@ void ifcopenshell::geometry::CgalShape::Triangulate(ifcopenshell::geometry::Sett try { CGAL::Polygon_mesh_processing::compute_face_normals(*shape_to_use, face_normals_map); } catch (...) { - Logger::Message(Logger::LOG_ERROR, "GEO", 68, "Face normal calculation failed"); + logger.Message(Logger::LOG_ERROR, "GEO", 68, "Face normal calculation failed"); return; } @@ -791,7 +791,7 @@ bool ifcopenshell::geometry::CgalShape::surface_area_along_direction(double tol, #ifndef IFOPSH_SIMPLE_KERNEL -void ifcopenshell::geometry::CgalShapeHalfSpaceDecomposition::Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int item_id, int surface_style_id) const { +void ifcopenshell::geometry::CgalShapeHalfSpaceDecomposition::Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int item_id, int surface_style_id, Logger& logger) const { throw std::runtime_error("Not implemented"); } diff --git a/src/ifcgeom/kernels/cgal/CgalConversionResult.h b/src/ifcgeom/kernels/cgal/CgalConversionResult.h index f0fb6c224c..b361e13332 100644 --- a/src/ifcgeom/kernels/cgal/CgalConversionResult.h +++ b/src/ifcgeom/kernels/cgal/CgalConversionResult.h @@ -185,7 +185,7 @@ namespace ifcopenshell { namespace geometry { mutable boost::optional> nef_; #endif public: - CgalShape(const cgal_shape_t& shape, bool convex = false); + CgalShape(const cgal_shape_t& shape, bool convex = false, Logger& logger = Logger::Root()); #ifndef IFOPSH_SIMPLE_KERNEL CgalShape(const CGAL::Nef_polyhedron_3& shape, bool convex = false) { @@ -209,7 +209,7 @@ namespace ifcopenshell { namespace geometry { operator const cgal_shape_t& () const { to_poly(); return *shape_; } const cgal_shape_t& poly() const { to_poly(); return *shape_; } - virtual void Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int item_id, int surface_style_id) const; + virtual void Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int item_id, int surface_style_id, Logger& logger = Logger::Root()) const; virtual void Serialize(const ifcopenshell::geometry::taxonomy::matrix4& place, std::string&) const; virtual IfcGeom::ConversionResultShape* clone() const { @@ -285,7 +285,7 @@ namespace ifcopenshell { namespace geometry { planes_.push_back(shape); } - virtual void Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int item_id, int surface_style_id) const; + virtual void Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int item_id, int surface_style_id, Logger& logger = Logger::Root()) const; virtual void Serialize(const ifcopenshell::geometry::taxonomy::matrix4& place, std::string&) const; virtual int surface_genus() const; diff --git a/src/ifcgeom/kernels/cgal/CgalKernel.cpp b/src/ifcgeom/kernels/cgal/CgalKernel.cpp index f2686d7a36..6a0935559b 100644 --- a/src/ifcgeom/kernels/cgal/CgalKernel.cpp +++ b/src/ifcgeom/kernels/cgal/CgalKernel.cpp @@ -46,18 +46,19 @@ namespace { struct PolyhedronBuilder : public CGAL::Modifier_base::HalfedgeDS> { private: std::list *face_list; + Logger& logger_; public: boost::optional from_soup; - PolyhedronBuilder(std::list *face_list); + PolyhedronBuilder(std::list *face_list, Logger& logger = Logger::Root()); void operator()(CGAL::Polyhedron_3::HalfedgeDS &hds); }; } -CGAL::Polyhedron_3 ifcopenshell::geometry::utils::create_polyhedron(std::list &face_list, bool stitch_borders) { +CGAL::Polyhedron_3 ifcopenshell::geometry::utils::create_polyhedron(std::list &face_list, bool stitch_borders, Logger& logger) { // Naive creation CGAL::Polyhedron_3 polyhedron; - PolyhedronBuilder builder(&face_list); + PolyhedronBuilder builder(&face_list, logger); polyhedron.delegate(builder); if (builder.from_soup) { polyhedron = *builder.from_soup; @@ -76,7 +77,7 @@ CGAL::Polyhedron_3 ifcopenshell::geometry::utils::create_polyhedron(std polyhedron.normalize_border(); if (!polyhedron.is_valid(false, 1)) { - Logger::Message(Logger::LOG_ERROR, "GEO", 69, "create_polyhedron: Polyhedron not valid!"); + logger.Message(Logger::LOG_ERROR, "GEO", 69, "create_polyhedron: Polyhedron not valid!"); // std::ofstream fresult; // fresult.open("/Users/ken/Desktop/invalid.off"); // fresult << polyhedron << std::endl; @@ -90,31 +91,31 @@ CGAL::Polyhedron_3 ifcopenshell::geometry::utils::create_polyhedron(std } #ifndef IFOPSH_SIMPLE_KERNEL -CGAL::Polyhedron_3 ifcopenshell::geometry::utils::create_polyhedron(const CGAL::Nef_polyhedron_3& nef_polyhedron) { +CGAL::Polyhedron_3 ifcopenshell::geometry::utils::create_polyhedron(const CGAL::Nef_polyhedron_3& nef_polyhedron, Logger& logger) { if (nef_polyhedron.is_simple()) { try { CGAL::Polyhedron_3 polyhedron; nef_polyhedron.convert_to_polyhedron(polyhedron); return polyhedron; } catch (...) { - Logger::Message(Logger::LOG_ERROR, "GEO", 70, "Conversion from Nef to polyhedron failed!"); + logger.Message(Logger::LOG_ERROR, "GEO", 70, "Conversion from Nef to polyhedron failed!"); return CGAL::Polyhedron_3(); } } else { - Logger::Message(Logger::LOG_ERROR, "GEO", 71, "Nef polyhedron not simple: cannot create polyhedron!"); + logger.Message(Logger::LOG_ERROR, "GEO", 71, "Nef polyhedron not simple: cannot create polyhedron!"); return CGAL::Polyhedron_3(); } } -CGAL::Nef_polyhedron_3 ifcopenshell::geometry::utils::create_nef_polyhedron(std::list &face_list) { - CGAL::Polyhedron_3 polyhedron = create_polyhedron(face_list); +CGAL::Nef_polyhedron_3 ifcopenshell::geometry::utils::create_nef_polyhedron(std::list &face_list, Logger& logger) { + CGAL::Polyhedron_3 polyhedron = create_polyhedron(face_list, true, logger); if (polyhedron.is_closed()) { try { if (!CGAL::Polygon_mesh_processing::is_outward_oriented(polyhedron)) { CGAL::Polygon_mesh_processing::reverse_face_orientations(polyhedron); } } catch (CGAL::Failure_exception& e) { - Logger::Message(Logger::LOG_ERROR, "GEO", 72, e); + logger.Message(Logger::LOG_ERROR, "GEO", 72, e); } } CGAL::Polygon_mesh_processing::triangulate_faces(polyhedron); @@ -122,12 +123,12 @@ CGAL::Nef_polyhedron_3 ifcopenshell::geometry::utils::create_nef_polyhe try { nef_polyhedron = CGAL::Nef_polyhedron_3(polyhedron); } catch (...) { - Logger::Message(Logger::LOG_ERROR, "GEO", 73, "Conversion to Nef polyhedron failed!"); + logger.Message(Logger::LOG_ERROR, "GEO", 73, "Conversion to Nef polyhedron failed!"); } return nef_polyhedron; } -CGAL::Nef_polyhedron_3 ifcopenshell::geometry::utils::create_nef_polyhedron(CGAL::Polyhedron_3 &polyhedron) { +CGAL::Nef_polyhedron_3 ifcopenshell::geometry::utils::create_nef_polyhedron(CGAL::Polyhedron_3 &polyhedron, Logger& logger) { // @todo needed? polyhedron.normalize_border(); @@ -137,7 +138,7 @@ CGAL::Nef_polyhedron_3 ifcopenshell::geometry::utils::create_nef_polyhe CGAL::Polygon_mesh_processing::reverse_face_orientations(polyhedron); } } catch (CGAL::Failure_exception& e) { - Logger::Message(Logger::LOG_ERROR, "GEO", 74, e); + logger.Message(Logger::LOG_ERROR, "GEO", 74, e); } } @@ -148,11 +149,11 @@ CGAL::Nef_polyhedron_3 ifcopenshell::geometry::utils::create_nef_polyhe try { nef_polyhedron = CGAL::Nef_polyhedron_3(polyhedron); } catch (...) { - Logger::Message(Logger::LOG_ERROR, "GEO", 75, "Conversion to Nef polyhedron failed!"); + logger.Message(Logger::LOG_ERROR, "GEO", 75, "Conversion to Nef polyhedron failed!"); } return nef_polyhedron; } else { - Logger::Message(Logger::LOG_ERROR, "GEO", 76, "Polyhedron not valid: cannot create Nef polyhedron!"); + logger.Message(Logger::LOG_ERROR, "GEO", 76, "Polyhedron not valid: cannot create Nef polyhedron!"); return CGAL::Nef_polyhedron_3(); } } @@ -161,13 +162,13 @@ CGAL::Nef_polyhedron_3 ifcopenshell::geometry::utils::create_nef_polyhe bool CgalKernel::convert(const taxonomy::shell::ptr l, cgal_shape_t& shape) { for (auto& f : l->children) { if (f->basis && f->basis->kind() != taxonomy::PLANE) { - Logger::Error("UNS", 3, "CGAL Kernel: Non-planar faces not supported at the moment"); + logger_.Error("UNS", 3, "CGAL Kernel: Non-planar faces not supported at the moment"); throw not_supported_error(); } for (auto& w : f->children) { for (auto& e : w->children) { if (e->basis && e->basis->kind() == taxonomy::BSPLINE_CURVE) { - Logger::Error("UNS", 4, "CGAL Kernel: B-spline edge curves not supported at the moment"); + logger_.Error("UNS", 4, "CGAL Kernel: B-spline edge curves not supported at the moment"); throw not_supported_error(); } } @@ -196,9 +197,9 @@ bool CgalKernel::convert(const taxonomy::shell::ptr l, cgal_shape_t& shape) { double volume = diag(0) * diag(1) * diag(2); // @todo volume van be zero also.. double density = num_points / volume; - Logger::Notice("GEO", 77, "Density " + boost::lexical_cast(density), l->instance); + logger_.Notice("GEO", 77, "Density " + boost::lexical_cast(density), l->instance); if (density > 5000) { - Logger::Notice("GEO", 78, "Substituted element with " + boost::lexical_cast(density) + " vertices / m3 with a bounding box"); + logger_.Notice("GEO", 78, "Substituted element with " + boost::lexical_cast(density) + " vertices / m3 with a bounding box"); CGAL::Point_3 lower(minmax.first(0), minmax.first(1), minmax.first(2)); CGAL::Point_3 upper(minmax.second(0), minmax.second(1), minmax.second(2)); shape = utils::create_cube(lower, upper); @@ -214,7 +215,7 @@ bool CgalKernel::convert(const taxonomy::shell::ptr l, cgal_shape_t& shape) { } catch (...) {} if (!success) { - Logger::Message(Logger::LOG_WARNING, "GEO", 79, "Failed to convert face:", f->instance); + logger_.Message(Logger::LOG_WARNING, "GEO", 79, "Failed to convert face:", f->instance); continue; } @@ -236,7 +237,7 @@ bool CgalKernel::convert(const taxonomy::face::ptr face, std::list& } if (face->children.size() > 1 && num_outer_bounds > 1 && face->children.size() != num_outer_bounds) { - Logger::Message(Logger::LOG_ERROR, "GEO", 80, "Invalid configuration of boundaries for:", face->instance); + logger_.Message(Logger::LOG_ERROR, "GEO", 80, "Invalid configuration of boundaries for:", face->instance); return false; } @@ -249,7 +250,7 @@ bool CgalKernel::convert(const taxonomy::face::ptr face, std::list& cgal_wire_t wire; if (!convert(bound, wire)) { - Logger::Message(Logger::LOG_ERROR, "GEO", 81, "Failed to process face boundary loop", bound->instance); + logger_.Message(Logger::LOG_ERROR, "GEO", 81, "Failed to process face boundary loop", bound->instance); return false; } @@ -703,7 +704,7 @@ bool CgalKernel::convert(const taxonomy::loop::ptr loop, cgal_wire_t& result) { if (d < 1.e-5) { points.erase(points.end() - 1); } else { - Logger::Warning("GEO", 82, "Loop not closed", loop->instance); + logger_.Warning("GEO", 82, "Loop not closed", loop->instance); } } @@ -717,7 +718,7 @@ bool CgalKernel::convert(const taxonomy::loop::ptr loop, cgal_wire_t& result) { // A loop should consist of at least three vertices std::size_t original_count = polygon.size(); if (original_count < 3) { - Logger::Warning("GEO", 83, "Not enough edges for:", loop->instance); + logger_.Warning("GEO", 83, "Not enough edges for:", loop->instance); return false; } @@ -728,14 +729,14 @@ bool CgalKernel::convert(const taxonomy::loop::ptr loop, cgal_wire_t& result) { std::size_t count = polygon.size(); if (original_count - count != 0) { std::stringstream ss; ss << (original_count - count) << " edges removed for:"; - Logger::Warning("GEO", 84, ss.str(), loop->instance); + logger_.Warning("GEO", 84, ss.str(), loop->instance); } { std::set visited_points; for (auto& p : polygon) { if (visited_points.find(p) != visited_points.end()) { - Logger::Error("GEO", 85, "Skipping self-intersecting loop", loop->instance); + logger_.Error("GEO", 85, "Skipping self-intersecting loop", loop->instance); // @todo signal somehow that occt kernel might be able to solve this // @todo implement cycle detection using Arrangement_2, but that only works in exact kernel return false; @@ -757,7 +758,7 @@ bool CgalKernel::convert(const taxonomy::loop::ptr loop, cgal_wire_t& result) { } if (do_segments_intersect(segments)) { - Logger::Message(Logger::LOG_WARNING, "GEO", 86, "Skipping self-intersecting loop", loop->instance); + logger_.Message(Logger::LOG_WARNING, "GEO", 86, "Skipping self-intersecting loop", loop->instance); return false; } @@ -785,7 +786,7 @@ bool CgalKernel::convert(const taxonomy::loop::ptr loop, cgal_wire_t& result) { */ if (count < 3) { - Logger::Message(Logger::LOG_ERROR, "GEO", 87, "Not enough edges for:", loop->instance); + logger_.Message(Logger::LOG_ERROR, "GEO", 87, "Not enough edges for:", loop->instance); return false; } @@ -819,7 +820,7 @@ bool CgalKernel::convert_impl(const taxonomy::shell::ptr shell, ConversionResult bool CgalKernel::convert_impl(const taxonomy::solid::ptr solid, ConversionResults& results) { if (solid->children.size() > 1) { - Logger::Error("UNS", 5, "Multiple shells in solid not supported at the moment"); + logger_.Error("UNS", 5, "Multiple shells in solid not supported at the moment"); return false; } cgal_shape_t shape; @@ -964,7 +965,7 @@ bool ifcopenshell::geometry::kernels::CgalKernel::convert_openings(const IfcUtil try { a.convert_to_polyhedron(a_poly); } catch (...) { - Logger::Message(Logger::LOG_ERROR, "GEO", 88, "Could not convert from Nef:", entity); + logger_.Message(Logger::LOG_ERROR, "GEO", 88, "Could not convert from Nef:", entity); return false; } @@ -1189,7 +1190,7 @@ bool CgalKernel::process_extrusion(const cgal_face_t& bottom_face, taxonomy::dir bool CgalKernel::convert(const taxonomy::extrusion::ptr extrusion, cgal_shape_t &shape) { const double& height = extrusion->depth; if (height < settings_.get().get()) { - Logger::Message(Logger::LOG_ERROR, "GEO", 89, "Non-positive extrusion height encountered for:", extrusion->instance); + logger_.Message(Logger::LOG_ERROR, "GEO", 89, "Non-positive extrusion height encountered for:", extrusion->instance); return false; } @@ -1325,13 +1326,13 @@ bool CgalKernel::preprocess_boolean_operand(const IfcUtil::IfcBaseClass* log_ref cgal_shape_t shape = shape_const; if (!shape.is_valid()) { - Logger::Message(Logger::LOG_ERROR, "GEO", 90, "Conversion to Nef will fail. Invalid geometry:", log_reference); + logger_.Message(Logger::LOG_ERROR, "GEO", 90, "Conversion to Nef will fail. Invalid geometry:", log_reference); return false; } if (!shape.is_closed()) { // TODO: There can be substractions to remove parts of non-volumetric objects. Maybe iterate over all faces of an entity and put them in a Nef_polyhedron_3 through Boolean union? Highly inefficient but maybe desirable... - Logger::Message(Logger::LOG_ERROR, "UNS", 6, "Subtraction of openings not supported for non-closed geometry:", log_reference); + logger_.Message(Logger::LOG_ERROR, "UNS", 6, "Subtraction of openings not supported for non-closed geometry:", log_reference); return false; } @@ -1340,18 +1341,18 @@ bool CgalKernel::preprocess_boolean_operand(const IfcUtil::IfcBaseClass* log_ref try { success = CGAL::Polygon_mesh_processing::triangulate_faces(shape); } catch (CGAL::Failure_exception& e) { - Logger::Notice("GEO", 91, e); - Logger::Message(Logger::LOG_ERROR, "GEO", 92, "Triangulation of geometry crashed:", log_reference); + logger_.Notice("GEO", 91, e); + logger_.Message(Logger::LOG_ERROR, "GEO", 92, "Triangulation of geometry crashed:", log_reference); return false; } if (!success) { - Logger::Message(Logger::LOG_ERROR, "GEO", 93, "Triangulation of geometry failed:", log_reference); + logger_.Message(Logger::LOG_ERROR, "GEO", 93, "Triangulation of geometry failed:", log_reference); return false; } if (CGAL::Polygon_mesh_processing::does_self_intersect(shape)) { - Logger::Message(Logger::LOG_ERROR, "GEO", 94, "Conversion to Nef will fail. Self-intersecting geometry:", log_reference); + logger_.Message(Logger::LOG_ERROR, "GEO", 94, "Conversion to Nef will fail. Self-intersecting geometry:", log_reference); return false; } @@ -1423,8 +1424,8 @@ bool CgalKernel::preprocess_boolean_operand(const IfcUtil::IfcBaseClass* log_ref try { result = CGAL::Nef_polyhedron_3(shape); } catch (CGAL::Failure_exception& e) { - Logger::Notice("GEO", 95, e); - Logger::Message(Logger::LOG_ERROR, "GEO", 96, "Could not convert geometry to Nef:", log_reference); + logger_.Notice("GEO", 95, e); + logger_.Message(Logger::LOG_ERROR, "GEO", 96, "Could not convert geometry to Nef:", log_reference); return false; } @@ -1496,8 +1497,8 @@ bool CgalKernel::preprocess_boolean_operand(const IfcUtil::IfcBaseClass* log_ref // @todo don't dilate in 3 dimensions but only in the XY plane, orthogonal to wall axis. result = CGAL::minkowski_sum_3(result, precision_cube_); } catch (CGAL::Failure_exception& e) { - Logger::Notice("GEO", 97, e); - Logger::Message(Logger::LOG_ERROR, "GEO", 98, "Could not dilate boolean operand", log_reference); + logger_.Notice("GEO", 97, e); + logger_.Message(Logger::LOG_ERROR, "GEO", 98, "Could not dilate boolean operand", log_reference); return false; } } @@ -1522,8 +1523,8 @@ bool CgalKernel::preprocess_boolean_operand(const IfcUtil::IfcBaseClass* log_ref cgal_shape_t convert_back; result.convert_to_polyhedron(convert_back); } catch (CGAL::Failure_exception& e) { - Logger::Notice("GEO", 99, e); - Logger::Message(Logger::LOG_WARNING, "GEO", 100, "Final conversion will likely fail. Could not convert geometry from Nef:", log_reference); + logger_.Notice("GEO", 99, e); + logger_.Message(Logger::LOG_WARNING, "GEO", 100, "Final conversion will likely fail. Could not convert geometry from Nef:", log_reference); } return true; @@ -1845,7 +1846,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result::ptr br, Conversion // even-odd fill rule will result in incorrect results. // See for example the Duplex model roof. - Logger::Notice("GEO", 101, "Holes are not disjoint"); + logger_.Notice("GEO", 101, "Holes are not disjoint"); CGAL::Polygon_set_2 result; auto it = loops.begin(); @@ -1898,7 +1899,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result::ptr br, Conversion ); }); - Logger::Notice("GEO", 102, "Processed boolean operation as 2d arrangement"); + logger_.Notice("GEO", 102, "Processed boolean operation as 2d arrangement"); return true; @@ -1984,7 +1985,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result::ptr br, Conversion ps.push_back({ p.x(), p.y() }); } if (!ps.is_simple()) { - Logger::Warning("GEO", 103, "Polygonal boundary not simple", face->children[0]->instance); + logger_.Warning("GEO", 103, "Polygonal boundary not simple", face->children[0]->instance); continue; } @@ -2130,7 +2131,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result::ptr br, Conversion try { a.convert_to_polyhedron(a_poly); } catch (...) { - Logger::Message(Logger::LOG_ERROR, "GEO", 104, "Could not convert geometry with openings from Nef:", br->instance); + logger_.Message(Logger::LOG_ERROR, "GEO", 104, "Could not convert geometry with openings from Nef:", br->instance); return false; } @@ -2145,8 +2146,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result::ptr br, Conversion #endif } -PolyhedronBuilder::PolyhedronBuilder(std::list* face_list) { - this->face_list = face_list; +PolyhedronBuilder::PolyhedronBuilder(std::list* face_list, Logger& logger) : face_list(face_list), logger_(logger) { } #include @@ -2222,7 +2222,7 @@ void PolyhedronBuilder::operator()(CGAL::Polyhedron_3::HalfedgeDS &hds) // For now let's just skip over the triangle. We can also use // the Aff_transformation_3 stored in place to convert the 2d // coords back to 3d. - Logger::Warning("GEO", 105, "Ignoring triangulated facet with novel point likely due to self-intersections"); + logger_.Warning("GEO", 105, "Ignoring triangulated facet with novel point likely due to self-intersections"); facet_vertices.erase(facet_vertices.end() - 1); break; } diff --git a/src/ifcgeom/kernels/cgal/CgalKernel.h b/src/ifcgeom/kernels/cgal/CgalKernel.h index ce6efbb2aa..1c9af2546e 100644 --- a/src/ifcgeom/kernels/cgal/CgalKernel.h +++ b/src/ifcgeom/kernels/cgal/CgalKernel.h @@ -20,6 +20,8 @@ #ifndef CGAL_KERNEL_H #define CGAL_KERNEL_H +#include "../../../ifcparse/IfcLogger.h" + /* #ifdef NO_CACHE @@ -58,12 +60,12 @@ namespace ifcopenshell { namespace utils { IFC_GEOMLIBRARY_API CGAL::Polyhedron_3 create_cube(double d); IFC_GEOMLIBRARY_API CGAL::Polyhedron_3 create_cube(const Kernel_::Point_3& lower, const Kernel_::Point_3& upper); - IFC_GEOMLIBRARY_API CGAL::Polyhedron_3 create_polyhedron(std::list &face_list, bool stitch_borders = false); + IFC_GEOMLIBRARY_API CGAL::Polyhedron_3 create_polyhedron(std::list &face_list, bool stitch_borders = false, Logger& logger = Logger::Root()); #ifndef IFOPSH_SIMPLE_KERNEL - IFC_GEOMLIBRARY_API CGAL::Polyhedron_3 create_polyhedron(const CGAL::Nef_polyhedron_3 &nef_polyhedron); - IFC_GEOMLIBRARY_API CGAL::Nef_polyhedron_3 create_nef_polyhedron(std::list &face_list); - IFC_GEOMLIBRARY_API CGAL::Nef_polyhedron_3 create_nef_polyhedron(CGAL::Polyhedron_3 &polyhedron); + IFC_GEOMLIBRARY_API CGAL::Polyhedron_3 create_polyhedron(const CGAL::Nef_polyhedron_3 &nef_polyhedron, Logger& logger = Logger::Root()); + IFC_GEOMLIBRARY_API CGAL::Nef_polyhedron_3 create_nef_polyhedron(std::list &face_list, Logger& logger = Logger::Root()); + IFC_GEOMLIBRARY_API CGAL::Nef_polyhedron_3 create_nef_polyhedron(CGAL::Polyhedron_3 &polyhedron, Logger& logger = Logger::Root()); #endif } @@ -91,12 +93,12 @@ namespace ifcopenshell { #endif public: - CgalKernel(const Settings& settings) - : AbstractKernel("cgal", settings) + CgalKernel(const Settings& settings, Logger& logger = Logger::Root()) + : AbstractKernel("cgal", settings, logger) {} virtual AbstractKernel* clone() const { - return new CgalKernel(settings()); + return new CgalKernel(settings(), logger()); } virtual bool supports_boolean_operations() const { @@ -133,4 +135,4 @@ namespace ifcopenshell { } } } -#endif \ No newline at end of file +#endif diff --git a/src/ifcgeom/kernels/opencascade/OpenCascadeConversionResult.cpp b/src/ifcgeom/kernels/opencascade/OpenCascadeConversionResult.cpp index 7d7ca54f78..38d7b12330 100644 --- a/src/ifcgeom/kernels/opencascade/OpenCascadeConversionResult.cpp +++ b/src/ifcgeom/kernels/opencascade/OpenCascadeConversionResult.cpp @@ -47,7 +47,7 @@ namespace { } } -void ifcopenshell::geometry::OpenCascadeShape::Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int item_id, int surface_style_id) const { +void ifcopenshell::geometry::OpenCascadeShape::Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int item_id, int surface_style_id, Logger& logger) const { // @todo remove duplication with OpenCascadeKernel::convert(const taxonomy::matrix4::ptr matrix, gp_GTrsf& trsf); // above can be static? @@ -87,7 +87,7 @@ void ifcopenshell::geometry::OpenCascadeShape::Triangulate(ifcopenshell::geometr try { BRepMesh_IncrementalMesh(shape_, settings.get().get(), false, settings.get().get()); } catch (...) { - Logger::Message(Logger::LOG_ERROR, "GEO", 183, "Failed to triangulate shape"); + Logger::Root().Message(Logger::LOG_ERROR, "GEO", 183, "Failed to triangulate shape"); return; } } @@ -113,7 +113,7 @@ void ifcopenshell::geometry::OpenCascadeShape::Triangulate(ifcopenshell::geometr Handle_Poly_Triangulation tri = BRep_Tool::Triangulation(face, loc); if (tri.IsNull()) { - Logger::Message(Logger::LOG_ERROR, "GEO", 184, "Triangulation missing for face"); + Logger::Root().Message(Logger::LOG_ERROR, "GEO", 184, "Triangulation missing for face"); } else { // Keep track of the number of times an edge is used // Manifold edges (i.e. edges used twice) are deemed invisible @@ -174,7 +174,7 @@ void ifcopenshell::geometry::OpenCascadeShape::Triangulate(ifcopenshell::geometr else triangles(i).Get(n1, n2, n3); if (dict[n1] == dict[n2] || dict[n2] == dict[n3] || dict[n3] == dict[n1]) { - Logger::Warning("GEO", 185, "Mesher generated a degenerate triangle, ignoring"); + logger.Warning("GEO", 185, "Mesher generated a degenerate triangle, ignoring"); continue; } @@ -619,7 +619,7 @@ namespace { try { BRepMesh_IncrementalMesh(s, tol); } catch (...) { - Logger::Message(Logger::LOG_ERROR, "GEO", 186, "Failed to triangulate shape"); + Logger::Root().Message(Logger::LOG_ERROR, "GEO", 186, "Failed to triangulate shape"); return; } meshed = true; diff --git a/src/ifcgeom/kernels/opencascade/OpenCascadeConversionResult.h b/src/ifcgeom/kernels/opencascade/OpenCascadeConversionResult.h index f34e27bf8e..927c9f3dac 100644 --- a/src/ifcgeom/kernels/opencascade/OpenCascadeConversionResult.h +++ b/src/ifcgeom/kernels/opencascade/OpenCascadeConversionResult.h @@ -53,7 +53,7 @@ namespace ifcopenshell { const TopoDS_Shape& shape() const { return shape_; } operator const TopoDS_Shape& () { return shape_; } - virtual void Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int item_id, int surface_style_id) const; + virtual void Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int item_id, int surface_style_id, Logger& logger = Logger::Root()) const; virtual void Serialize(const ifcopenshell::geometry::taxonomy::matrix4& place, std::string&) const; virtual IfcGeom::ConversionResultShape* clone() const { diff --git a/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.cpp b/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.cpp index 50c3feba11..b02312ed95 100644 --- a/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.cpp +++ b/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.cpp @@ -118,7 +118,7 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity* auto it3_shape = std::static_pointer_cast(it3->Shape())->shape(); if (it3_shape.IsNull()) { - Logger::Error("GEO", 187, "Null operand"); + Logger::Root().Error("GEO", 187, "Null operand"); continue; } @@ -143,7 +143,7 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity* IfcGeom::util::create_solid_from_faces(list, entity_part, settings_.get().get(), true); is_manifold = util::is_manifold(entity_part); if (is_manifold) { - Logger::Warning("GEO", 188, "Successfully sewed non-manifold first operand"); + Logger::Root().Warning("GEO", 188, "Successfully sewed non-manifold first operand"); } } @@ -161,17 +161,17 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity* failure = "Empty result (no faces) for BOPAlgo_MakerVolume; original was " + std::to_string(IfcGeom::util::count(entity_part, TopAbs_FACE)); } else { is_manifold = util::is_manifold(entity_part_2); - Logger::Warning("GEO", 189, std::string("Sucessfully detected exterior volume to non-manifold first operand; shape is now ") + (is_manifold ? std::string("manifold") : std::string("non-manifold"))); + Logger::Root().Warning("GEO", 189, std::string("Sucessfully detected exterior volume to non-manifold first operand; shape is now ") + (is_manifold ? std::string("manifold") : std::string("non-manifold"))); entity_part = entity_part_2; } } catch (const Standard_Failure& e) { failure.emplace(e.GetMessageString()); } if (failure) { - Logger::Warning("GEO", 190, "MakeVolume failed: " + *failure, entity); + Logger::Root().Warning("GEO", 190, "MakeVolume failed: " + *failure, entity); } } else { - Logger::Warning("GEO", 191, "Non-manifold first operand, use --make-volume to try and make manifold"); + Logger::Root().Warning("GEO", 191, "Non-manifold first operand, use --make-volume to try and make manifold"); } } @@ -214,7 +214,7 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity* if (util::boolean_operation(bst, result, opening_list, BOPAlgo_CUT, intermediate_result)) { result = intermediate_result; } else { - Logger::Message(Logger::LOG_ERROR, "GEO", 192, "Opening subtraction failed for " + boost::lexical_cast(std::distance(jt, it)) + " openings", entity); + Logger::Root().Message(Logger::LOG_ERROR, "GEO", 192, "Opening subtraction failed for " + boost::lexical_cast(std::distance(jt, it)) + " openings", entity); } jt = it; @@ -235,7 +235,7 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity* // where we keep the first operand as is (a compound of faces probably, // unless --orient-shells was activated in which case we're already lost). if (!is_manifold) { - Logger::Warning("GEO", 193, "Retrying boolean operation on individual faces"); + Logger::Root().Warning("GEO", 193, "Retrying boolean operation on individual faces"); } continue; } diff --git a/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.h b/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.h index add0c15a25..359ccbd01d 100644 --- a/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.h +++ b/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.h @@ -112,14 +112,14 @@ private: double precision_; public: - OpenCascadeKernel(const ifcopenshell::geometry::Settings& settings) - : AbstractKernel("opencascade", settings) + OpenCascadeKernel(const ifcopenshell::geometry::Settings& settings, Logger& logger = Logger::Root()) + : AbstractKernel("opencascade", settings, logger) , faceset_helper_(nullptr) , precision_(settings.get().get()) {} virtual AbstractKernel* clone() const { - return new OpenCascadeKernel(settings()); + return new OpenCascadeKernel(settings(), logger()); } virtual bool supports_boolean_operations() const { return true; } diff --git a/src/ifcgeom/kernels/opencascade/base_utils.cpp b/src/ifcgeom/kernels/opencascade/base_utils.cpp index 68482a068d..eeeac6c7c6 100644 --- a/src/ifcgeom/kernels/opencascade/base_utils.cpp +++ b/src/ifcgeom/kernels/opencascade/base_utils.cpp @@ -711,12 +711,12 @@ bool IfcGeom::util::create_solid_from_faces(const TopTools_ListOfShape& face_lis valid_shell &= util::count(shape, TopAbs_SHELL) > 0; } catch (const Standard_Failure& e) { if (e.GetMessageString() && strlen(e.GetMessageString())) { - Logger::Error("GEO", 106, e.GetMessageString()); + Logger::Root().Error("GEO", 106, e.GetMessageString()); } else { - Logger::Error("GEO", 107, "Unknown error sewing shell"); + Logger::Root().Error("GEO", 107, "Unknown error sewing shell"); } } catch (...) { - Logger::Error("GEO", 108, "Unknown error sewing shell"); + Logger::Root().Error("GEO", 108, "Unknown error sewing shell"); } if (valid_shell) { @@ -744,22 +744,22 @@ bool IfcGeom::util::create_solid_from_faces(const TopTools_ListOfShape& face_lis } } catch (const Standard_Failure& e) { if (e.GetMessageString() && strlen(e.GetMessageString())) { - Logger::Error("GEO", 109, e.GetMessageString()); + Logger::Root().Error("GEO", 109, e.GetMessageString()); } else { - Logger::Error("GEO", 110, "Unknown error classifying solid"); + Logger::Root().Error("GEO", 110, "Unknown error classifying solid"); } } catch (...) { - Logger::Error("GEO", 111, "Unknown error classifying solid"); + Logger::Root().Error("GEO", 111, "Unknown error classifying solid"); } } } catch (const Standard_Failure& e) { if (e.GetMessageString() && strlen(e.GetMessageString())) { - Logger::Error("GEO", 112, e.GetMessageString()); + Logger::Root().Error("GEO", 112, e.GetMessageString()); } else { - Logger::Error("GEO", 113, "Unknown error creating solid"); + Logger::Root().Error("GEO", 113, "Unknown error creating solid"); } } catch (...) { - Logger::Error("GEO", 114, "Unknown error creating solid"); + Logger::Root().Error("GEO", 114, "Unknown error creating solid"); } if (complete_shape.IsNull()) { @@ -771,7 +771,7 @@ bool IfcGeom::util::create_solid_from_faces(const TopTools_ListOfShape& face_lis B.MakeCompound(C); B.Add(C, complete_shape); complete_shape = C; - Logger::Warning("GEO", 115, "Multiple components in IfcConnectedFaceSet"); + Logger::Root().Warning("GEO", 115, "Multiple components in IfcConnectedFaceSet"); } B.Add(complete_shape, result_shape); } @@ -786,7 +786,7 @@ bool IfcGeom::util::create_solid_from_faces(const TopTools_ListOfShape& face_lis B.MakeCompound(C); B.Add(C, complete_shape); complete_shape = C; - Logger::Warning("GEO", 116, "Loose faces in IfcConnectedFaceSet"); + Logger::Root().Warning("GEO", 116, "Loose faces in IfcConnectedFaceSet"); } B.Add(complete_shape, loose_faces.Current()); } @@ -794,7 +794,7 @@ bool IfcGeom::util::create_solid_from_faces(const TopTools_ListOfShape& face_lis shape = complete_shape; } else { - Logger::Error("GEO", 117, "Failed to sew faceset"); + Logger::Root().Error("GEO", 117, "Failed to sew faceset"); } return valid_shell; @@ -898,7 +898,7 @@ bool IfcGeom::util::validate_shape(const TopoDS_Shape& s) { dump(s); - Logger::Warning("GEO", 118, str.str()); + Logger::Root().Warning("GEO", 118, str.str()); return false; } diff --git a/src/ifcgeom/kernels/opencascade/boolean_result.cpp b/src/ifcgeom/kernels/opencascade/boolean_result.cpp index d4f12afe30..2965d8590d 100644 --- a/src/ifcgeom/kernels/opencascade/boolean_result.cpp +++ b/src/ifcgeom/kernels/opencascade/boolean_result.cpp @@ -118,14 +118,14 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result::ptr br, Con const double first_operand_volume = util::shape_volume(a); if (first_operand_volume <= ALMOST_ZERO) { - Logger::Message(Logger::LOG_WARNING, "GEO", 119, "Empty solid for:", c->instance); + Logger::Root().Message(Logger::LOG_WARNING, "GEO", 119, "Empty solid for:", c->instance); } } else { for (auto& r : cr) { auto S = std::static_pointer_cast(r.Shape())->shape(); if (S.IsNull()) { - Logger::Error("GEO", 120, "Null operand"); + Logger::Root().Error("GEO", 120, "Null operand"); continue; } gp_GTrsf trsf; @@ -140,7 +140,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result::ptr br, Con // #2665 we also set a precision-independent threshold, because in the boolean op routine // the working fuzziness might still be increased. if (d < tol * 20. || d < 0.00002) { - Logger::Message(Logger::LOG_WARNING, "GEO", 121, "Halfspace subtraction yields unchanged volume:", c->instance); + Logger::Root().Message(Logger::LOG_WARNING, "GEO", 121, "Halfspace subtraction yields unchanged volume:", c->instance); continue; } else { S = result; diff --git a/src/ifcgeom/kernels/opencascade/boolean_utils.cpp b/src/ifcgeom/kernels/opencascade/boolean_utils.cpp index d326f29c74..f7eeb61d41 100644 --- a/src/ifcgeom/kernels/opencascade/boolean_utils.cpp +++ b/src/ifcgeom/kernels/opencascade/boolean_utils.cpp @@ -419,7 +419,7 @@ int IfcGeom::util::eliminate_narrow_operands(double prec, const TopTools_ListOfS bool is_narrow = min_dimension < prec; - Logger::Notice("GEO", 122, "Min OBB dimension of operand = " + std::to_string(min_dimension)); + Logger::Root().Notice("GEO", 122, "Min OBB dimension of operand = " + std::to_string(min_dimension)); if (!is_narrow) { c.Append(it.Value()); @@ -704,7 +704,7 @@ bool IfcGeom::util::boolean_subtraction_2d_using_builder(const TopoDS_Shape & a_ if (u11 < U1 && U1 < u12 && u21 < U2 && U2 < u22) { // Edge curves belonging to different operands intersect, don't process // using builder. - Logger::Notice("GEO", 123, "Intersecting boundaries"); + Logger::Root().Notice("GEO", 123, "Intersecting boundaries"); return false; } } @@ -751,7 +751,7 @@ bool IfcGeom::util::boolean_subtraction_2d_using_builder(const TopoDS_Shape & a_ // any effect and marked as redundant. Feeding it to the builder algo // will likely cause problems. redundant[std::distance(wires.begin(), it)] = true; - Logger::Notice("GEO", 124, "Subtraction operand outside of outer bound"); + Logger::Root().Notice("GEO", 124, "Subtraction operand outside of outer bound"); } } @@ -791,7 +791,7 @@ bool IfcGeom::util::boolean_subtraction_2d_using_builder(const TopoDS_Shape & a_ if (wire_clss[wire_index].Perform(p2d) == TopAbs_IN) { // A wire is contained within another operand redundant[other_index] = true; - Logger::Notice("GEO", 125, "Subtraction operand contained in other"); + Logger::Root().Notice("GEO", 125, "Subtraction operand contained in other"); } } } @@ -849,7 +849,7 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To std::stringstream ss; ss << "bool-" << std::this_thread::get_id() << "-" << (operation_counter_++); debug_identifier = ss.str(); - Logger::Notice("GEO", 126, "Boolean debug identifier: " + debug_identifier); + Logger::Root().Notice("GEO", 126, "Boolean debug identifier: " + debug_identifier); } if (fuzziness < 0.) { @@ -885,7 +885,7 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To a = unify(a_input, fuzziness * 1000.); - Logger::Message( + Logger::Root().Message( Logger::LOG_DEBUG, "GEO", 127, "Simplified operand A from "s + std::to_string(count(a_input, TopAbs_FACE)) + @@ -897,7 +897,7 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To TopTools_ListIteratorOfListOfShape it(b_input); for (; it.More(); it.Next()) { b.Append(unify(it.Value(), fuzziness)); - Logger::Message( + Logger::Root().Message( Logger::LOG_DEBUG, "GEO", 128, "Simplified operand B from "s + std::to_string(count(it.Value(), TopAbs_FACE)) + @@ -925,7 +925,7 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To auto N = bounding_box_overlap(fuzziness, a, b, b_tmp); if (N) { - Logger::Notice("GEO", 129, "Eliminated " + std::to_string(N) + " disjoint operands"); + Logger::Root().Notice("GEO", 129, "Eliminated " + std::to_string(N) + " disjoint operands"); std::swap(b, b_tmp); } } @@ -936,7 +936,7 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To b_tmp.Clear(); auto N = eliminate_touching_operands(fuzziness, a, b, b_tmp); if (N) { - Logger::Notice("GEO", 130, "Eliminated " + std::to_string(N) + " touching operands"); + Logger::Root().Notice("GEO", 130, "Eliminated " + std::to_string(N) + " touching operands"); std::swap(b, b_tmp); } } @@ -947,7 +947,7 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To b_tmp.Clear(); auto N = eliminate_narrow_operands(fuzziness, b, b_tmp); if (N) { - Logger::Notice("GEO", 131, "Eliminated " + std::to_string(N) + " narrow operands"); + Logger::Root().Notice("GEO", 131, "Eliminated " + std::to_string(N) + " narrow operands"); std::swap(b, b_tmp); } } @@ -961,21 +961,21 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To } if (b.Extent() == 0) { - Logger::Warning("GEO", 132, "No other operands remaining, using first operand"); + Logger::Root().Warning("GEO", 132, "No other operands remaining, using first operand"); result = a; return true; } - if (!is_2d && Logger::LOG_NOTICE >= Logger::Verbosity()) { + if (!is_2d && Logger::LOG_NOTICE >= Logger::Root().Verbosity()) { PERF("preliminary manifoldness check"); if (!a.IsNull()) { - Logger::Notice("GEO", 133, "Operand A is " + (is_manifold(a) ? ""s : "non-"s) + "manifold"); + Logger::Root().Notice("GEO", 133, "Operand A is " + (is_manifold(a) ? ""s : "non-"s) + "manifold"); } TopTools_ListIteratorOfListOfShape it(b); for (int i = 0; it.More(); it.Next(), ++i) { - Logger::Notice("GEO", 134, "Operand B " + std::to_string(i) + " is " + (is_manifold(it.Value()) ? ""s : "non-"s) + "manifold"); + Logger::Root().Notice("GEO", 134, "Operand B " + std::to_string(i) + " is " + (is_manifold(it.Value()) ? ""s : "non-"s) + "manifold"); } } @@ -1015,7 +1015,7 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To const double fuzz = (std::min)(min_length_orig / 3., fuzziness); - Logger::Notice("GEO", 135, "Used fuzziness: " + std::to_string(fuzz)); + Logger::Root().Notice("GEO", 135, "Used fuzziness: " + std::to_string(fuzz)); const double new_fuzziness = fuzziness * 10.; const bool allow_retry = new_fuzziness - 1e-15 <= settings.precision * 10000. && new_fuzziness < min_length_orig; @@ -1049,7 +1049,7 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To } if (is_extrusion_a) { - Logger::Notice("GEO", 136, "Operand A 1/1 is an extrusion"); + Logger::Root().Notice("GEO", 136, "Operand A 1/1 is an extrusion"); TopTools_ListIteratorOfListOfShape it(b); for (int nb = 1; it.More(); it.Next(), ++nb) { @@ -1065,10 +1065,10 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To } if (is_extrusion_b) { - Logger::Notice("GEO", 137, "Operand B " + std::to_string(nb) + "/" + std::to_string(b.Extent()) + " is an extrusion"); + Logger::Root().Notice("GEO", 137, "Operand B " + std::to_string(nb) + "/" + std::to_string(b.Extent()) + " is an extrusion"); if (b_interval.first < a_interval.first + (fuzz * 100.) && b_interval.second > a_interval.second - (fuzz * 100.)) { - Logger::Notice("GEO", 138, "Operand B creates a through hole"); + Logger::Root().Notice("GEO", 138, "Operand B creates a through hole"); // Align b with a operand gp_Trsf trsf; @@ -1108,23 +1108,23 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To BRepPrimAPI_MakePrism mp(face_result, gp_Vec(gp::DY()) * (a_interval.second - a_interval.first)); if (mp.IsDone()) { if (b_remainder_3d.Extent()) { - Logger::Notice("GEO", 139, std::to_string(b_remainder_3d.Extent()) + " operands remaining to process in 3D"); + Logger::Root().Notice("GEO", 139, std::to_string(b_remainder_3d.Extent()) + " operands remaining to process in 3D"); b = b_remainder_3d; s1s.Clear(); s1s.Append(mp.Shape()); } else { - Logger::Notice("GEO", 140, "Processed fully in 2D"); + Logger::Root().Notice("GEO", 140, "Processed fully in 2D"); result = mp.Shape(); return true; } } else { - Logger::Notice("GEO", 141, "Failed to extrude 2D boolean result. Retrying in 3D."); + Logger::Root().Notice("GEO", 141, "Failed to extrude 2D boolean result. Retrying in 3D."); } } else { - Logger::Notice("GEO", 142, "Failed to perform 2D boolean operation. Retrying in 3D."); + Logger::Root().Notice("GEO", 142, "Failed to perform 2D boolean operation. Retrying in 3D."); } } else { - Logger::Notice("GEO", 143, "No second operands can be processed as 2D inner bounds. Retrying in 3D."); + Logger::Root().Notice("GEO", 143, "No second operands can be processed as 2D inner bounds. Retrying in 3D."); } } } @@ -1146,7 +1146,7 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To } if (builder->IsDone()) { if (false && builder->DSFiller()->HasWarning(STANDARD_TYPE(BOPAlgo_AlertAcquiredSelfIntersection))) { - Logger::Notice("GEO", 144, "Builder reports self-intersection in output"); + Logger::Root().Notice("GEO", 144, "Builder reports self-intersection in output"); success = false; /* @@ -1160,7 +1160,7 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To } */ } else if(builder->DSFiller()->HasWarning(STANDARD_TYPE(BOPAlgo_AlertBadPositioning)) && !TopoDS_Iterator(*builder).More()) { - Logger::Notice("GEO", 145, "Builder reports bad positioning and result is empty"); + Logger::Root().Notice("GEO", 145, "Builder reports bad positioning and result is empty"); success = false; } else { TopoDS_Shape r = *builder; @@ -1174,7 +1174,7 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To fix.Perform(); r = fix.Shape(); } catch (...) { - Logger::Error("GEO", 146, "Shape healing failed on boolean result"); + Logger::Root().Error("GEO", 146, "Shape healing failed on boolean result"); } } @@ -1185,7 +1185,7 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To success = ana.IsValid() != 0; if (!success) { - Logger::Notice("GEO", 147, "Boolean operation yields invalid result"); + Logger::Root().Notice("GEO", 147, "Boolean operation yields invalid result"); std::stringstream str; bool any_emitted = false; @@ -1215,7 +1215,7 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To dump(r); - Logger::Notice("GEO", 148, str.str()); + Logger::Root().Notice("GEO", 148, str.str()); } } @@ -1335,7 +1335,7 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To if (op == BOPAlgo_CUT && has_open_shells && all_faces_included_in_result && result_n_faces > first_op_n_faces) { success = false; - Logger::Notice("GEO", 149, "Boolean result discarded because subtractions results in only the addition of faces"); + Logger::Root().Notice("GEO", 149, "Boolean result discarded because subtractions results in only the addition of faces"); } else { // when there are edges or vertex-edge distances close to the used fuzziness, the // output is not trusted and the operation is attempted with a higher fuzziness. @@ -1381,7 +1381,7 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To static const char* const reason_strings[] = { "edge length", "vertex-edge", "face-face" }; std::stringstream str; str << "Boolean operation result failing " << reason_strings[reason] << " interference check, with fuzziness " << fuzziness << " with length " << v; - Logger::Notice("GEO", 150, str.str()); + Logger::Root().Notice("GEO", 150, str.str()); } } @@ -1390,7 +1390,7 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To } } else { - Logger::Notice("GEO", 151, "Boolean operation yields non-manifold result"); + Logger::Root().Notice("GEO", 151, "Boolean operation yields non-manifold result"); } } } @@ -1400,7 +1400,7 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To #if OCC_VERSION_HEX >= 0x70200 if (builder->HasError(STANDARD_TYPE(BOPAlgo_AlertBOPNotAllowed))) { - Logger::Error("GEO", 152, "Invalid operands. Using first operand"); + Logger::Root().Error("GEO", 152, "Invalid operands. Using first operand"); result = a; success = true; } @@ -1413,14 +1413,14 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To #endif std::string str_str = str.str(); if (str_str.size()) { - Logger::Notice("GEO", 153, str_str); + Logger::Root().Notice("GEO", 153, str_str); } } if (!success) { if (allow_retry) { return boolean_operation(settings, a, b, op, result, new_fuzziness); } else { - Logger::Notice("GEO", 154, "No longer attempting boolean operation with higher fuzziness"); + Logger::Root().Notice("GEO", 154, "No longer attempting boolean operation with higher fuzziness"); } } return success && !result.IsNull(); diff --git a/src/ifcgeom/kernels/opencascade/extrusion.cpp b/src/ifcgeom/kernels/opencascade/extrusion.cpp index dec6defd31..606dc7f39e 100644 --- a/src/ifcgeom/kernels/opencascade/extrusion.cpp +++ b/src/ifcgeom/kernels/opencascade/extrusion.cpp @@ -10,7 +10,7 @@ bool OpenCascadeKernel::convert(const taxonomy::extrusion::ptr extrusion, TopoDS const double& height = extrusion->depth; if (height < settings_.get().get()) { - Logger::Error("GEO", 155, "Non-positive extrusion height encountered for:", extrusion->instance); + Logger::Root().Error("GEO", 89, "Non-positive extrusion height encountered for:", extrusion->instance); return false; } diff --git a/src/ifcgeom/kernels/opencascade/face.cpp b/src/ifcgeom/kernels/opencascade/face.cpp index e1cda4e272..6f52c03561 100644 --- a/src/ifcgeom/kernels/opencascade/face.cpp +++ b/src/ifcgeom/kernels/opencascade/face.cpp @@ -169,7 +169,7 @@ namespace { } else if (crv_or_wire.which() == 2) { // @todo const double precision_ = 1.e-5; - Logger::Warning("GEO", 156, "Approximating BasisCurve due to possible discontinuities", i->instance); + Logger::Root().Warning("GEO", 156, "Approximating BasisCurve due to possible discontinuities", i->instance); const auto& w = boost::get(crv_or_wire); #if OCC_VERSION_HEX < 0x70600 BRepAdaptor_CompCurve cc(w, true); @@ -289,12 +289,12 @@ bool OpenCascadeKernel::convert(const taxonomy::face::ptr face, TopoDS_Shape& re // the face will still be processed as long as there are no holes. A compound of faces // is returned in that case. if (num_bounds > 1 && num_outer_bounds > 1 && num_bounds != num_outer_bounds) { - Logger::Message(Logger::LOG_ERROR, "GEO", 157, "Invalid configuration of boundaries for:", face->instance); + Logger::Root().Message(Logger::LOG_ERROR, "GEO", 157, "Invalid configuration of boundaries for:", face->instance); return false; } if (num_outer_bounds > 1) { - Logger::Message(Logger::LOG_WARNING, "GEO", 158, "Multiple outer boundaries for:", face->instance); + Logger::Root().Message(Logger::LOG_WARNING, "GEO", 158, "Multiple outer boundaries for:", face->instance); fd.all_outer() = true; } @@ -315,11 +315,11 @@ bool OpenCascadeKernel::convert(const taxonomy::face::ptr face, TopoDS_Shape& re TopoDS_Wire wire; if (faceset_helper_ && bound->is_polyhedron()) { if (!faceset_helper_->wire(bound, wire)) { - Logger::Message(Logger::LOG_WARNING, "GEO", 159, "Face boundary loop not included", bound->instance); + Logger::Root().Message(Logger::LOG_WARNING, "GEO", 159, "Face boundary loop not included", bound->instance); continue; } } else if (!convert(bound, wire)) { - Logger::Message(Logger::LOG_ERROR, "GEO", 160, "Failed to process face boundary loop", bound->instance); + Logger::Root().Message(Logger::LOG_ERROR, "GEO", 160, "Failed to process face boundary loop", bound->instance); return false; } @@ -336,7 +336,7 @@ bool OpenCascadeKernel::convert(const taxonomy::face::ptr face, TopoDS_Shape& re }; TopTools_ListOfShape results; if (settings.use_wire_intersection_check && util::wire_intersections(wire, results, settings)) { - Logger::Warning("GEO", 161, "Self-intersections with " + boost::lexical_cast(results.Extent()) + " cycles detected"); + Logger::Root().Warning("GEO", 161, "Self-intersections with " + boost::lexical_cast(results.Extent()) + " cycles detected"); util::select_largest(results, wire); } @@ -347,7 +347,7 @@ bool OpenCascadeKernel::convert(const taxonomy::face::ptr face, TopoDS_Shape& re } if (fd.wires().empty()) { - Logger::Warning("GEO", 162, "Face with no boundaries", face->instance); + Logger::Root().Warning("GEO", 162, "Face with no boundaries", face->instance); return false; } @@ -404,7 +404,7 @@ bool OpenCascadeKernel::convert(const taxonomy::face::ptr face, TopoDS_Shape& re if (fd.surface().IsNull()) { // The set of wires is triangulated in case no surface can be found - Logger::Message(Logger::LOG_WARNING, "GEO", 163, "Triangulating face boundaries for face", face->instance); + Logger::Root().Message(Logger::LOG_WARNING, "GEO", 163, "Triangulating face boundaries for face", face->instance); if (fd.all_outer()) { for (const auto& w : fd.wires()) { @@ -457,7 +457,7 @@ bool OpenCascadeKernel::convert(const taxonomy::face::ptr face, TopoDS_Shape& re kt.Value().Original().ToUTF8CString(c); std::string message = c; delete[] c; - Logger::Warning("GEO", 164, message, face->instance); + Logger::Root().Warning("GEO", 164, message, face->instance); } } @@ -469,17 +469,17 @@ bool OpenCascadeKernel::convert(const taxonomy::face::ptr face, TopoDS_Shape& re if (it.Value().ShapeType() == TopAbs_FACE) { face_list.Append(it.Value()); } else { - Logger::Error("UNS", 7, "Unsupported output from face healing"); + Logger::Root().Error("UNS", 7, "Unsupported output from face healing"); } } } else { - Logger::Error("UNS", 8, "Unsupported output from face healing"); + Logger::Root().Error("UNS", 8, "Unsupported output from face healing"); } } else { face_list.Append(f); } } else { - Logger::Error("GEO", 165, "Internal error in face creation"); + Logger::Root().Error("GEO", 165, "Internal error in face creation"); return false; } } else { @@ -520,14 +520,14 @@ bool OpenCascadeKernel::convert(const taxonomy::face::ptr face, TopoDS_Shape& re delete[] c; #if OCC_VERSION_MAJOR==7 && OCC_VERSION_MINOR >= 7 if (!reversed_surface && !fd.surface().IsNull() && fd.surface()->IsUPeriodic() && message == "Unknown message invoked with the keyword FixAdvFace.FixOrientation.MSG0") { - Logger::Notice("GEO", 166, "Detected reversed wire, reattempting with reversed basis surface"); + Logger::Root().Notice("GEO", 166, "Detected reversed wire, reattempting with reversed basis surface"); TopoDS_Face reversed_result; convert(face, reversed_result, true); result = reversed_result; return true; } else #endif - Logger::Warning("GEO", 167, message, face->instance); + Logger::Root().Warning("GEO", 167, message, face->instance); } } } diff --git a/src/ifcgeom/kernels/opencascade/faceset_helper.cpp b/src/ifcgeom/kernels/opencascade/faceset_helper.cpp index 06928b2624..dd943fd5e4 100644 --- a/src/ifcgeom/kernels/opencascade/faceset_helper.cpp +++ b/src/ifcgeom/kernels/opencascade/faceset_helper.cpp @@ -149,7 +149,7 @@ IfcGeom::OpenCascadeKernel::faceset_helper::faceset_helper( auto num_retained = std::count(retained.begin(), retained.end(), true); if (unique.size() != num_retained) { - Logger::Notice("GEO", 168, "Collapsed vertices from " + std::to_string(pnts.size()) + " (" + std::to_string(unique.size()) + " unique) to " + std::to_string(num_retained)); + Logger::Root().Notice("GEO", 168, "Collapsed vertices from " + std::to_string(pnts.size()) + " (" + std::to_string(unique.size()) + " unique) to " + std::to_string(num_retained)); } typedef std::array edge_t; @@ -205,7 +205,7 @@ IfcGeom::OpenCascadeKernel::faceset_helper::faceset_helper( } if (duplicates_.size() || loops_removed || (non_manifold && shell->closed.get_value_or(false))) { - Logger::Warning("GEO", 169, boost::lexical_cast(duplicate_faces) + " duplicate faces removed, " + boost::lexical_cast(loops_removed) + " degenerate loops eliminated and " + boost::lexical_cast(non_manifold) + " non-manifold edges"); + Logger::Root().Warning("GEO", 169, boost::lexical_cast(duplicate_faces) + " duplicate faces removed, " + boost::lexical_cast(loops_removed) + " degenerate loops eliminated and " + boost::lexical_cast(non_manifold) + " non-manifold edges"); } } @@ -276,7 +276,7 @@ bool IfcGeom::OpenCascadeKernel::faceset_helper::wires(const ifcopenshell::geome !kernel_->settings().get().get(), 0., kernel_->settings().get().get()})) { - Logger::Warning("GEO", 170, "Self-intersections with " + boost::lexical_cast(results.Extent()) + " cycles detected"); + Logger::Root().Warning("GEO", 170, "Self-intersections with " + boost::lexical_cast(results.Extent()) + " cycles detected"); non_manifold_ = true; wires = results; } else { diff --git a/src/ifcgeom/kernels/opencascade/layerset.cpp b/src/ifcgeom/kernels/opencascade/layerset.cpp index 0ef83a9787..c1abe45817 100644 --- a/src/ifcgeom/kernels/opencascade/layerset.cpp +++ b/src/ifcgeom/kernels/opencascade/layerset.cpp @@ -129,7 +129,7 @@ namespace { } } - Logger::Error("GEO", 171, "Unable to map layer geometry to material index"); + Logger::Root().Error("GEO", 171, "Unable to map layer geometry to material index"); return false; } } @@ -234,7 +234,7 @@ bool IfcGeom::util::apply_folded_layerset(const ConversionResults& items, const if (s.ShapeType() == TopAbs_SHELL) { shells.Append(TopoDS::Shell(s)); } else { - Logger::Error("GEO", 172, "Expected shell type in layerset processing"); + Logger::Root().Error("GEO", 172, "Expected shell type in layerset processing"); return false; } } @@ -433,12 +433,12 @@ bool IfcGeom::util::split_solid_by_shell(const TopoDS_Shape& input, const TopoDS } } catch (const Standard_Failure& e) { if (e.GetMessageString() && strlen(e.GetMessageString())) { - Logger::Error("GEO", 173, e.GetMessageString()); + Logger::Root().Error("GEO", 173, e.GetMessageString()); } else { - Logger::Error("GEO", 174, "Unknown error performing fixes"); + Logger::Root().Error("GEO", 174, "Unknown error performing fixes"); } } catch (...) { - Logger::Error("GEO", 175, "Unknown error performing fixes"); + Logger::Root().Error("GEO", 175, "Unknown error performing fixes"); } BRepCheck_Analyzer analyser(shape); bool is_valid = analyser.IsValid() != 0; @@ -448,7 +448,7 @@ bool IfcGeom::util::split_solid_by_shell(const TopoDS_Shape& input, const TopoDS } if (is_null[0] || is_null[1]) { - Logger::Message(Logger::LOG_ERROR, "GEO", 176, "Null result obtained from layerset slicing"); + Logger::Root().Message(Logger::LOG_ERROR, "GEO", 176, "Null result obtained from layerset slicing"); if (is_null[0] && is_null[1]) { return false; } diff --git a/src/ifcgeom/kernels/opencascade/loft.cpp b/src/ifcgeom/kernels/opencascade/loft.cpp index 54ec982b07..19d62e1aa2 100644 --- a/src/ifcgeom/kernels/opencascade/loft.cpp +++ b/src/ifcgeom/kernels/opencascade/loft.cpp @@ -83,7 +83,7 @@ bool OpenCascadeKernel::convert(const taxonomy::loft::ptr loft, TopoDS_Shape& re if (non_polygonal) { if (loft->children.size() < 2) { - Logger::Error("GEO", 177, "Not enough sections to loft"); + Logger::Root().Error("GEO", 177, "Not enough sections to loft"); return false; } @@ -124,7 +124,7 @@ bool OpenCascadeKernel::convert(const taxonomy::loft::ptr loft, TopoDS_Shape& re auto first_wire_count = sections.front().size(); for (auto& section : sections) { if (section.size() != first_wire_count) { - Logger::Error("GEO", 178, "Inconsistent number of wires in sections"); + Logger::Root().Error("GEO", 178, "Inconsistent number of wires in sections"); return false; } } @@ -261,7 +261,7 @@ bool OpenCascadeKernel::convert(const taxonomy::loft::ptr loft, TopoDS_Shape& re */ if (shps.size() < 2) { - Logger::Error("GEO", 179, "Not enough sections to loft"); + Logger::Root().Error("GEO", 179, "Not enough sections to loft"); return false; } diff --git a/src/ifcgeom/kernels/opencascade/loop.cpp b/src/ifcgeom/kernels/opencascade/loop.cpp index f9ee8ad666..4329dec3d9 100644 --- a/src/ifcgeom/kernels/opencascade/loop.cpp +++ b/src/ifcgeom/kernels/opencascade/loop.cpp @@ -129,7 +129,7 @@ namespace { } else { // @todo const double precision_ = 1.e-5; - Logger::Warning("GEO", 180, "Approximating BasisCurve due to possible discontinuities", e->instance); + Logger::Root().Warning("GEO", 180, "Approximating BasisCurve due to possible discontinuities", e->instance); const auto& w = boost::get(crv_or_wire); #if OCC_VERSION_HEX < 0x70600 BRepAdaptor_CompCurve cc(w, true); @@ -266,7 +266,7 @@ bool OpenCascadeKernel::convert(const taxonomy::loop::ptr loop, TopoDS_Wire& wir } if (converted_segments.Extent() == 0) { - Logger::Message(Logger::LOG_ERROR, "GEO", 181, "No segment successfully converted:", loop->instance); + Logger::Root().Message(Logger::LOG_ERROR, "GEO", 181, "No segment successfully converted:", loop->instance); return false; } @@ -331,7 +331,7 @@ bool OpenCascadeKernel::convert(const taxonomy::loop::ptr loop, TopoDS_Wire& wir if (ang < 0.0314) { edges_to_tesselate.Add(crv1->DynamicType() == STANDARD_TYPE(Geom_Circle) ? edges.First() : edges.Last()); - Logger::Notice("GEO", 182, "Sharp circular corner detecting, substituting with linear approximation"); + Logger::Root().Notice("GEO", 182, "Sharp circular corner detecting, substituting with linear approximation"); } } } diff --git a/src/ifcgeom/kernels/opencascade/shell.cpp b/src/ifcgeom/kernels/opencascade/shell.cpp index 74e3abcb6b..943b3f0efb 100644 --- a/src/ifcgeom/kernels/opencascade/shell.cpp +++ b/src/ifcgeom/kernels/opencascade/shell.cpp @@ -46,19 +46,19 @@ bool OpenCascadeKernel::convert(const taxonomy::shell::ptr l, TopoDS_Shape& shap try { success = convert(face, occ_face); } catch (const std::exception& e) { - Logger::Error("GEO", 194, e); + Logger::Root().Error("GEO", 194, e); } catch (const Standard_Failure& e) { if (e.GetMessageString() && strlen(e.GetMessageString())) { - Logger::Error("GEO", 195, e.GetMessageString()); + Logger::Root().Error("GEO", 195, e.GetMessageString()); } else { - Logger::Error("GEO", 196, "Unknown error creating face"); + Logger::Root().Error("GEO", 196, "Unknown error creating face"); } } catch (...) { - Logger::Error("GEO", 197, "Unknown error creating face"); + Logger::Root().Error("GEO", 197, "Unknown error creating face"); } if (!success) { - Logger::Message(Logger::LOG_WARNING, "GEO", 198, "Failed to convert face:", face->instance); + Logger::Root().Message(Logger::LOG_WARNING, "GEO", 198, "Failed to convert face:", face->instance); continue; } @@ -71,7 +71,7 @@ bool OpenCascadeKernel::convert(const taxonomy::shell::ptr l, TopoDS_Shape& shap if (face_area(triangle) > min_face_area) { face_list.Append(triangle); } else { - Logger::Message(Logger::LOG_WARNING, "GEO", 199, "Degenerate face:", face->instance); + Logger::Root().Message(Logger::LOG_WARNING, "GEO", 199, "Degenerate face:", face->instance); } } } @@ -79,7 +79,7 @@ bool OpenCascadeKernel::convert(const taxonomy::shell::ptr l, TopoDS_Shape& shap if (face_area(occ_face) > min_face_area) { face_list.Append(occ_face); } else { - Logger::Message(Logger::LOG_WARNING, "GEO", 200, "Degenerate face:", face->instance); + Logger::Root().Message(Logger::LOG_WARNING, "GEO", 200, "Degenerate face:", face->instance); } } } diff --git a/src/ifcgeom/kernels/opencascade/solid.cpp b/src/ifcgeom/kernels/opencascade/solid.cpp index 94a2447f3b..8fcccfab17 100644 --- a/src/ifcgeom/kernels/opencascade/solid.cpp +++ b/src/ifcgeom/kernels/opencascade/solid.cpp @@ -92,7 +92,7 @@ bool OpenCascadeKernel::convert(const taxonomy::solid::ptr solid, TopoDS_Shape& throw std::runtime_error("Unexpected configuration of subshapes"); } } else { - Logger::Warning("GEO", 201, "Ignored shell", s->instance); + Logger::Root().Warning("GEO", 201, "Ignored shell", s->instance); } } if (!S.IsNull()) { diff --git a/src/ifcgeom/kernels/opencascade/sweep_along_curve.cpp b/src/ifcgeom/kernels/opencascade/sweep_along_curve.cpp index 95597a523a..4e10ffc14b 100644 --- a/src/ifcgeom/kernels/opencascade/sweep_along_curve.cpp +++ b/src/ifcgeom/kernels/opencascade/sweep_along_curve.cpp @@ -130,7 +130,7 @@ bool OpenCascadeKernel::convert(const taxonomy::sweep_along_curve::ptr scs, Topo auto w = convert_curve(scs->curve); if (w.which() != 2) { - Logger::Error("UNS", 9, "Unsupported directrix"); + Logger::Root().Error("UNS", 9, "Unsupported directrix"); return false; } TopoDS_Shape face_; @@ -178,7 +178,7 @@ bool OpenCascadeKernel::convert(const taxonomy::sweep_along_curve::ptr scs, Topo for (TopExp_Explorer exp(wire, TopAbs_VERTEX); exp.More(); exp.Next()) { if (pln.Distance(BRep_Tool::Pnt(TopoDS::Vertex(exp.Current()))) > ALMOST_ZERO) { directrix_on_plane = false; - Logger::Message(Logger::LOG_WARNING, "GEO", 202, "The Directrix does not lie on the ReferenceSurface", scs->instance); + Logger::Root().Message(Logger::LOG_WARNING, "GEO", 202, "The Directrix does not lie on the ReferenceSurface", scs->instance); break; } } diff --git a/src/ifcgeom/kernels/opencascade/sweep_utils.cpp b/src/ifcgeom/kernels/opencascade/sweep_utils.cpp index 824466b24e..4c96516479 100644 --- a/src/ifcgeom/kernels/opencascade/sweep_utils.cpp +++ b/src/ifcgeom/kernels/opencascade/sweep_utils.cpp @@ -97,7 +97,7 @@ bool IfcGeom::util::wire_to_ax(const TopoDS_Wire & wire, gp_Ax2 & directrix) { Handle(Geom_Curve) crv = BRep_Tool::Curve(edge, u0, u1); crv->D1(u0, directrix_origin, directrix_tangent); } else { - Logger::Error("GEO", 203, "Unable to locate first edge"); + Logger::Root().Error("GEO", 203, "Unable to locate first edge"); return false; } @@ -187,7 +187,7 @@ void IfcGeom::util::sort_edges(const TopoDS_Wire & wire, std::vector 2) { - Logger::Warning("GEO", 204, "Self-intersecting Directrix"); + Logger::Root().Warning("GEO", 204, "Self-intersecting Directrix"); } } diff --git a/src/ifcgeom/kernels/opencascade/wire_builder.cpp b/src/ifcgeom/kernels/opencascade/wire_builder.cpp index 9a5368c356..29d6e5b3ef 100644 --- a/src/ifcgeom/kernels/opencascade/wire_builder.cpp +++ b/src/ifcgeom/kernels/opencascade/wire_builder.cpp @@ -116,12 +116,12 @@ bool IfcGeom::util::create_edge_over_curve_with_log_messages(const Handle_Geom_C } } if (dmin == std::numeric_limits::infinity()) { - Logger::Error("GEO", 205, "No extrema for point"); + Logger::Root().Error("GEO", 205, "No extrema for point"); } else if (dmin > eps2) { - Logger::Error("GEO", 206, "Distance of " + boost::lexical_cast(std::sqrt(dmin)) + " exceeds tolerance"); + Logger::Root().Error("GEO", 206, "Distance of " + boost::lexical_cast(std::sqrt(dmin)) + " exceeds tolerance"); } } else { - Logger::Error("GEO", 207, "Failed to calculate extrema for point"); + Logger::Root().Error("GEO", 207, "Failed to calculate extrema for point"); } } } @@ -171,7 +171,7 @@ void IfcGeom::util::wire_builder::operator()(const TopoDS_Shape& a, const TopoDS if (dist > 1000. * p_) { mw_.Add(w1); mw_.Add(BRepBuilderAPI_MakeEdge(p1, p2)); - Logger::Warning("GEO", 208, "Added additional segment to close gap with length " + boost::lexical_cast(dist) + " to:", inst_); + Logger::Root().Warning("GEO", 208, "Added additional segment to close gap with length " + boost::lexical_cast(dist) + " to:", inst_); goto check; } @@ -199,28 +199,28 @@ void IfcGeom::util::wire_builder::operator()(const TopoDS_Shape& a, const TopoDS // Preferably adjust the segment that is linear if (is_line1 || (is_circle1 && !is_line2)) { mw_.Add(adjust(w1, w12, p2)); - Logger::Notice("GEO", 209, "Adjusted edge end-point with distance " + boost::lexical_cast(dist) + " on:", inst_); + Logger::Root().Notice("GEO", 209, "Adjusted edge end-point with distance " + boost::lexical_cast(dist) + " on:", inst_); } else if ((is_line2 || is_circle2) && !last) { mw_.Add(w1); override_next_ = true; next_override_ = p1; - Logger::Notice("GEO", 210, "Adjusted edge end-point with distance " + boost::lexical_cast(dist) + " on:", inst_); + Logger::Root().Notice("GEO", 210, "Adjusted edge end-point with distance " + boost::lexical_cast(dist) + " on:", inst_); } else { // In all other cases an edge is added mw_.Add(w1); mw_.Add(BRepBuilderAPI_MakeEdge(p1, p2)); - Logger::Warning("GEO", 211, "Added additional segment to close gap with length " + boost::lexical_cast(dist) + " to:", inst_); + Logger::Root().Warning("GEO", 211, "Added additional segment to close gap with length " + boost::lexical_cast(dist) + " to:", inst_); } } else { - Logger::Error("GEO", 212, "Internal error, inconsistent wire segments", inst_); + Logger::Root().Error("GEO", 212, "Internal error, inconsistent wire segments", inst_); mw_.Add(w1); } } check: if (mw_.Error() == BRepBuilderAPI_NonManifoldWire) { - Logger::Error("GEO", 213, "Non-manifold curve segments:", inst_); + Logger::Root().Error("GEO", 213, "Non-manifold curve segments:", inst_); } else if (mw_.Error() == BRepBuilderAPI_DisconnectedWire) { - Logger::Error("GEO", 214, "Failed to join curve segments:", inst_); + Logger::Root().Error("GEO", 214, "Failed to join curve segments:", inst_); } } \ No newline at end of file diff --git a/src/ifcgeom/kernels/opencascade/wire_utils.cpp b/src/ifcgeom/kernels/opencascade/wire_utils.cpp index f01f550da9..5fb0c3d085 100644 --- a/src/ifcgeom/kernels/opencascade/wire_utils.cpp +++ b/src/ifcgeom/kernels/opencascade/wire_utils.cpp @@ -86,7 +86,7 @@ bool IfcGeom::util::approximate_plane_through_wire(const TopoDS_Wire& wire, gp_P // obtaining a 2d points for the Delaunay, infinity is passed here, so this // can't for assessing degenerativeness. if (v.Magnitude() < 1.e-7) { - Logger::Warning("GEO", 215, "Degenerate face boundary in normal estimation"); + Logger::Root().Warning("GEO", 215, "Degenerate face boundary in normal estimation"); return false; } @@ -233,7 +233,7 @@ IfcGeom::util::triangulate_wire_result IfcGeom::util::triangulate_wire(const std auto it = mapping.find(uvnodes[k]); if (it == mapping.end()) { - Logger::Error("GEO", 216, "Internal error: unable to unproject uv-mesh"); + Logger::Root().Error("GEO", 216, "Internal error: unable to unproject uv-mesh"); return TRIANGULATE_WIRE_FAIL; } @@ -277,7 +277,7 @@ IfcGeom::util::triangulate_wire_result IfcGeom::util::triangulate_wire(const std } faces.Append(triangle_face); } else { - Logger::Error("GEO", 217, "Internal error: missing face"); + Logger::Root().Error("GEO", 217, "Internal error: missing face"); return TRIANGULATE_WIRE_FAIL; } } @@ -308,7 +308,7 @@ IfcGeom::util::triangulate_wire_result IfcGeom::util::triangulate_wire(const std if (!contains) { #endif // All existing edges need to exist in the new faces - Logger::Error("GEO", 218, "Internal error, missing edge from triangulation"); + Logger::Root().Error("GEO", 218, "Internal error, missing edge from triangulation"); non_manifold = true; } } @@ -319,7 +319,7 @@ IfcGeom::util::triangulate_wire_result IfcGeom::util::triangulate_wire(const std // Existing edges are boundaries with use 1 // New edges are internal with use 2 if (n != (mape.Contains(v) ? 1 : 2)) { - Logger::Error("GEO", 219, "Internal error, non-manifold result from triangulation"); + Logger::Root().Error("GEO", 219, "Internal error, non-manifold result from triangulation"); non_manifold = true; } } @@ -790,12 +790,12 @@ bool IfcGeom::util::fill_nonmanifold_wires_with_planar_faces(TopoDS_Shape& shape shape = solid.SolidFromShell(TopoDS::Shell(shape)); } catch (const Standard_Failure& e) { if (e.GetMessageString() && strlen(e.GetMessageString())) { - Logger::Error("GEO", 220, e.GetMessageString()); + Logger::Root().Error("GEO", 220, e.GetMessageString()); } else { - Logger::Error("GEO", 221, "Unknown error creating solid"); + Logger::Root().Error("GEO", 221, "Unknown error creating solid"); } } catch (...) { - Logger::Error("GEO", 222, "Unknown error creating solid"); + Logger::Root().Error("GEO", 222, "Unknown error creating solid"); } return true; @@ -808,12 +808,12 @@ bool IfcGeom::util::convert_curve_to_wire(const Handle(Geom_Curve)& curve, TopoD return true; } catch (const Standard_Failure& e) { if (e.GetMessageString() && strlen(e.GetMessageString())) { - Logger::Error("GEO", 223, e.GetMessageString()); + Logger::Root().Error("GEO", 223, e.GetMessageString()); } else { - Logger::Error("GEO", 224, "Unknown error converting curve to wire"); + Logger::Root().Error("GEO", 224, "Unknown error converting curve to wire"); } } catch (...) { - Logger::Error("GEO", 225, "Unknown error converting curve to wire"); + Logger::Root().Error("GEO", 225, "Unknown error converting curve to wire"); } return false; } @@ -834,7 +834,7 @@ void IfcGeom::util::assert_closed_wire(TopoDS_Wire& wire, double tol) { wire = mw.Wire(); } - Logger::Warning("GEO", 226, "Wire not closed"); + Logger::Root().Warning("GEO", 226, "Wire not closed"); } } @@ -844,7 +844,7 @@ bool IfcGeom::util::convert_wire_to_face(const TopoDS_Wire& w, TopoDS_Face& face TopTools_ListOfShape results; if (settings.use_wire_intersection_check && util::wire_intersections(wire, results, settings)) { - Logger::Warning("GEO", 227, "Self-intersections with " + boost::lexical_cast(results.Extent()) + " cycles detected"); + Logger::Root().Warning("GEO", 227, "Self-intersections with " + boost::lexical_cast(results.Extent()) + " cycles detected"); util::select_largest(results, wire); } @@ -875,7 +875,7 @@ bool IfcGeom::util::convert_wire_to_face(const TopoDS_Wire& w, TopoDS_Face& face BRepBuilderAPI_FaceError er = mf.Error(); if (er != BRepBuilderAPI_FaceDone) { - Logger::Error("GEO", 228, "Failed to create face."); + Logger::Root().Error("GEO", 228, "Failed to create face."); return false; } face = mf.Face(); @@ -902,7 +902,7 @@ bool IfcGeom::util::convert_wire_to_faces(const TopoDS_Wire& w, TopoDS_Compound& TopTools_ListOfShape results; if (settings.use_wire_intersection_check && util::wire_intersections(w, results, settings)) { - Logger::Warning("GEO", 229, "Self-intersections with " + boost::lexical_cast(results.Extent()) + " cycles detected"); + Logger::Root().Warning("GEO", 229, "Self-intersections with " + boost::lexical_cast(results.Extent()) + " cycles detected"); } else { results.Clear(); results.Append(w); @@ -928,7 +928,7 @@ bool IfcGeom::util::convert_wire_to_faces(const TopoDS_Wire& w, TopoDS_Compound& BRepBuilderAPI_FaceError er = mf.Error(); if (er != BRepBuilderAPI_FaceDone) { - Logger::Error("GEO", 230, "Failed to create face."); + Logger::Root().Error("GEO", 230, "Failed to create face."); continue; } @@ -945,7 +945,7 @@ bool IfcGeom::util::convert_wire_to_faces(const TopoDS_Wire& w, TopoDS_Compound& if (p.first >= max_area / 10.) { B.Add(faces, p.second); } else { - Logger::Warning("GEO", 231, "Ignoring self-intersection loop with area " + boost::lexical_cast(p.first)); + Logger::Root().Warning("GEO", 231, "Ignoring self-intersection loop with area " + boost::lexical_cast(p.first)); } } diff --git a/src/ifcgeom/mapping/IfcAxis1Placement.cpp b/src/ifcgeom/mapping/IfcAxis1Placement.cpp index 4aa6b143d4..da85a53ba6 100644 --- a/src/ifcgeom/mapping/IfcAxis1Placement.cpp +++ b/src/ifcgeom/mapping/IfcAxis1Placement.cpp @@ -28,7 +28,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis1Placement* inst) { taxonomy::point3::ptr v = taxonomy::cast(map(inst->Location())); P = *v->components_; } catch (const std::exception&) { - Logger::Warning("GEO", 232, "Placement with invalid Location:", inst); + logger_.Warning("GEO", 232, "Placement with invalid Location:", inst); } const bool hasAxis = inst->Axis(); if (hasAxis) { diff --git a/src/ifcgeom/mapping/IfcAxis2Placement2D.cpp b/src/ifcgeom/mapping/IfcAxis2Placement2D.cpp index c747d44bd7..0d3b575353 100644 --- a/src/ifcgeom/mapping/IfcAxis2Placement2D.cpp +++ b/src/ifcgeom/mapping/IfcAxis2Placement2D.cpp @@ -29,7 +29,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis2Placement2D* inst) { taxonomy::point3::ptr v = taxonomy::cast(map(inst->Location())); P = *v->components_; } catch (const std::exception&) { - Logger::Warning("GEO", 233, "Placement with invalid Location:", inst); + logger_.Warning("GEO", 233, "Placement with invalid Location:", inst); } const bool hasRef = !!inst->RefDirection(); if (hasRef) { diff --git a/src/ifcgeom/mapping/IfcAxis2Placement3D.cpp b/src/ifcgeom/mapping/IfcAxis2Placement3D.cpp index 422d755070..f89e23a57b 100644 --- a/src/ifcgeom/mapping/IfcAxis2Placement3D.cpp +++ b/src/ifcgeom/mapping/IfcAxis2Placement3D.cpp @@ -29,13 +29,13 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis2Placement3D* inst) { taxonomy::point3::ptr v = taxonomy::cast(map(inst->Location())); o = *v->components_; } catch (const std::exception&) { - Logger::Warning("GEO", 234, "Placement with invalid Location:", inst); + logger_.Warning("GEO", 234, "Placement with invalid Location:", inst); } const bool hasAxis = !!inst->Axis(); const bool hasRef = !!inst->RefDirection(); if (hasAxis != hasRef) { - Logger::Warning("GEO", 235, "Axis and RefDirection should be specified together", inst); + logger_.Warning("GEO", 235, "Axis and RefDirection should be specified together", inst); } if (hasAxis) { diff --git a/src/ifcgeom/mapping/IfcAxis2PlacementLinear.cpp b/src/ifcgeom/mapping/IfcAxis2PlacementLinear.cpp index 7888893aa0..56bd140cdb 100644 --- a/src/ifcgeom/mapping/IfcAxis2PlacementLinear.cpp +++ b/src/ifcgeom/mapping/IfcAxis2PlacementLinear.cpp @@ -26,7 +26,7 @@ using namespace ifcopenshell::geometry; taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis2PlacementLinear* inst) { if (!inst->Location()->as()) { - Logger::Error("GEO", 236, std::runtime_error("Location must be IfcPointByDistanceExpression for IfcAxis2PlacementLinear")); + logger_.Error("GEO", 236, std::runtime_error("Location must be IfcPointByDistanceExpression for IfcAxis2PlacementLinear")); } Eigen::Vector3d o, axis(0, 0, 1), refDirection; diff --git a/src/ifcgeom/mapping/IfcCShapeProfileDef.cpp b/src/ifcgeom/mapping/IfcCShapeProfileDef.cpp index 44f17669c6..fcf4909d5b 100644 --- a/src/ifcgeom/mapping/IfcCShapeProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcCShapeProfileDef.cpp @@ -43,7 +43,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCShapeProfileDef* inst) { const double tol = settings_.get().get(); if ( x < tol || y < tol || d1 < tol || d2 < tol) { - Logger::Message(Logger::LOG_NOTICE, "GEO", 241, "Skipping zero sized profile:", inst); + logger_.Message(Logger::LOG_NOTICE, "GEO", 241, "Skipping zero sized profile:", inst); return nullptr; } diff --git a/src/ifcgeom/mapping/IfcCircle.cpp b/src/ifcgeom/mapping/IfcCircle.cpp index d647bcf041..f76b195e92 100644 --- a/src/ifcgeom/mapping/IfcCircle.cpp +++ b/src/ifcgeom/mapping/IfcCircle.cpp @@ -26,7 +26,7 @@ using namespace ifcopenshell::geometry; taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCircle* inst) { const double r = inst->Radius() * length_unit_; if (r < settings_.get().get()) { - Logger::Message(Logger::LOG_ERROR, "GEO", 237, "Radius not greater than zero for:", inst); + logger_.Message(Logger::LOG_ERROR, "GEO", 237, "Radius not greater than zero for:", inst); return nullptr; } diff --git a/src/ifcgeom/mapping/IfcCompositeCurve.cpp b/src/ifcgeom/mapping/IfcCompositeCurve.cpp index 6306771760..e45d28600c 100644 --- a/src/ifcgeom/mapping/IfcCompositeCurve.cpp +++ b/src/ifcgeom/mapping/IfcCompositeCurve.cpp @@ -34,11 +34,11 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCompositeCurve* inst) { for (auto& segment : *segments) { if (segment->as() && segment->as()->ParentCurve()->as()) { - Logger::Notice("GEO", 238, "Infinite IfcLine used as ParentCurve of segment, treating as a segment", segment); + logger_.Notice("GEO", 238, "Infinite IfcLine used as ParentCurve of segment, treating as a segment", segment); double u0 = 0.0; double u1 = segment->as()->ParentCurve()->as()->Dir()->Magnitude() * length_unit_; if (u1 < settings_.get().get()) { - Logger::Warning("GEO", 239, "Segment length below tolerance", segment); + logger_.Warning("GEO", 239, "Segment length below tolerance", segment); } auto e = taxonomy::make(); @@ -70,7 +70,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCompositeCurve* inst) { e->end = 2.0 * boost::math::constants::pi(); loop->children.push_back(e); } else { - Logger::Warning("GEO", 240, "Unexpected segment type", segment); + logger_.Warning("GEO", 240, "Unexpected segment type", segment); return nullptr; } } diff --git a/src/ifcgeom/mapping/IfcCurveSegment.cpp b/src/ifcgeom/mapping/IfcCurveSegment.cpp index fd60e28f56..5f917cd034 100644 --- a/src/ifcgeom/mapping/IfcCurveSegment.cpp +++ b/src/ifcgeom/mapping/IfcCurveSegment.cpp @@ -260,7 +260,7 @@ class curve_segment_evaluator { } } } else { - Logger::Warning("GEO", 242, "IfcCurveSegment belongs to multiple IfcCompositeCurve instances. Cannot determine the next segment."); + logger_.Warning("GEO", 242, "IfcCurveSegment belongs to multiple IfcCompositeCurve instances. Cannot determine the next segment."); } } @@ -283,7 +283,7 @@ class curve_segment_evaluator { if ((is_horizontal + is_vertical + is_cant) != 1) { // We have to choose the correct functor based on usage. We can't // support multiple, because we don't know the caller at this point. - Logger::Error("UNS", 10, std::runtime_error("multiple uses of IfcSegmentCurve not supported"), inst_); + logger_.Error("UNS", 10, std::runtime_error("multiple uses of IfcSegmentCurve not supported"), inst_); } segment_type_ = is_horizontal ? ST_HORIZONTAL : is_vertical ? ST_VERTICAL : is_cant ? ST_CANT : ST_HORIZONTAL; @@ -321,7 +321,7 @@ class curve_segment_evaluator { end_point = segmented_reference_curve->EndPoint(); } } else { - Logger::Warning("GEO", 243, "IfcCurveSegment belongs to multiple IfcCompositeCurve instances. Cannot determine the end point."); + logger_.Warning("GEO", 243, "IfcCurveSegment belongs to multiple IfcCompositeCurve instances. Cannot determine the end point."); } if (end_point) { next_segment_placement_ = taxonomy::cast(mapping_->map(end_point))->ccomponents(); @@ -343,7 +343,7 @@ class curve_segment_evaluator { taxonomy::ptr get_segment_curve_function() { if (!parent_curve_fn_ || !parent_curve_start_point_) { - Logger::Error("UNS", 11, std::runtime_error(inst_->ParentCurve()->declaration().name() + " not implemented"), inst_); + logger_.Error("UNS", 11, std::runtime_error(inst_->ParentCurve()->declaration().name() + " not implemented"), inst_); } auto length = fabs(this->length()); @@ -476,13 +476,13 @@ class curve_segment_evaluator { projected_length_ = length_; } } else if (segment_type_ == ST_CANT) { - Logger::Error("GEO", 244, std::runtime_error("Unexpected segment type encountered - cant is handled in set_cant_spiral_function - should never get here")); + logger_.Error("GEO", 244, std::runtime_error("Unexpected segment type encountered - cant is handled in set_cant_spiral_function - should never get here")); parent_curve_fn_ = std::make_shared( [](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); }, [](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); } ); } else { - Logger::Error("GEO", 245, std::runtime_error("Unexpected segment type encountered")); + logger_.Error("GEO", 245, std::runtime_error("Unexpected segment type encountered")); parent_curve_fn_ = std::make_shared( [](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); }, [](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); } @@ -643,13 +643,13 @@ class curve_segment_evaluator { set_cant_spiral_function(*super, *slope, cant); } else if (segment_type_ == ST_VERTICAL) { - Logger::Error("GEO", 246, std::runtime_error("IfcCosineSpiral cannot be used for vertical alignment")); + logger_.Error("GEO", 246, std::runtime_error("IfcCosineSpiral cannot be used for vertical alignment")); parent_curve_fn_ = std::make_shared( [](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); }, [](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); } ); } else { - Logger::Error("GEO", 247, std::runtime_error("Unexpected segment type encountered")); + logger_.Error("GEO", 247, std::runtime_error("Unexpected segment type encountered")); parent_curve_fn_ = std::make_shared( [](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); }, [](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); } @@ -712,12 +712,12 @@ class curve_segment_evaluator { set_cant_spiral_function(*super, *slope, cant); } else if (segment_type_ == ST_VERTICAL) { - Logger::Error("GEO", 248, std::runtime_error("IfcSineSpiral cannot be used for vertical alignment")); + logger_.Error("GEO", 248, std::runtime_error("IfcSineSpiral cannot be used for vertical alignment")); parent_curve_fn_ = std::make_shared( [](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); }, [](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); }); } else { - Logger::Error("GEO", 249, std::runtime_error("Unexpected segment type encountered")); + logger_.Error("GEO", 249, std::runtime_error("Unexpected segment type encountered")); parent_curve_fn_ = std::make_shared( [](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); }, [](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); }); @@ -976,12 +976,12 @@ class curve_segment_evaluator { } } else if (segment_type_ == ST_CANT) { - Logger::Warning("UNS", 12, std::runtime_error("Use of IfcCircle for cant is not supported")); + logger_.Warning("UNS", 12, std::runtime_error("Use of IfcCircle for cant is not supported")); parent_curve_fn_ = std::make_shared( [](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); }, [](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); }); } else { - Logger::Error("GEO", 250, std::runtime_error("Unexpected segment type encountered")); + logger_.Error("GEO", 250, std::runtime_error("Unexpected segment type encountered")); parent_curve_fn_ = std::make_shared( [](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); }, [](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); }); @@ -1067,7 +1067,7 @@ class curve_segment_evaluator { parent_curve_start_point_ = (*parent_curve_fn_)(start_); } else { - Logger::Warning("GEO", 251, std::runtime_error("Unexpected segment type encountered")); + logger_.Warning("GEO", 251, std::runtime_error("Unexpected segment type encountered")); parent_curve_fn_ = std::make_shared( [](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); }, [](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); }); @@ -1081,7 +1081,7 @@ class curve_segment_evaluator { auto coeffY = pc->CoefficientsY().get_value_or(std::vector()); auto coeffZ = pc->CoefficientsZ().get_value_or(std::vector()); if (!coeffZ.empty()) { - Logger::Warning("GEO", 252, "Expected IfcPolynomialCurve.CoefficientsZ to be undefined for alignment geometry. Coefficients ignored.", pc); + logger_.Warning("GEO", 252, "Expected IfcPolynomialCurve.CoefficientsZ to be undefined for alignment geometry. Coefficients ignored.", pc); } if (segment_type_ == ST_HORIZONTAL || segment_type_ == ST_VERTICAL) { @@ -1147,7 +1147,7 @@ class curve_segment_evaluator { auto result = boost::math::tools::bracket_and_solve_root(f, x, 2.0, true, tol, max_iter); x = result.first; } catch (...) { - Logger::Warning("GEO", 253, "root solver failed"); + logger_.Warning("GEO", 253, "root solver failed"); } return x; }; @@ -1208,12 +1208,12 @@ class curve_segment_evaluator { parent_curve_start_point_ = (*parent_curve_fn_)(0.0); // start is added to u in parent_curve_fn_, so use 0.0 here } else if (segment_type_ == ST_CANT) { - Logger::Warning("UNS", 13, std::runtime_error("Use of IfcPolynomialCurve for cant is not supported")); + logger_.Warning("UNS", 13, std::runtime_error("Use of IfcPolynomialCurve for cant is not supported")); parent_curve_fn_ = std::make_shared( [](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); }, [](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); }); } else { - Logger::Error("GEO", 254, std::runtime_error("Unexpected segment type encountered")); + logger_.Error("GEO", 254, std::runtime_error("Unexpected segment type encountered")); parent_curve_fn_ = std::make_shared( [](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); }, [](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); }); diff --git a/src/ifcgeom/mapping/IfcEdge.cpp b/src/ifcgeom/mapping/IfcEdge.cpp index 465fb1a08f..67cb4a4995 100644 --- a/src/ifcgeom/mapping/IfcEdge.cpp +++ b/src/ifcgeom/mapping/IfcEdge.cpp @@ -23,14 +23,14 @@ using namespace ifcopenshell::geometry; taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEdge* inst) { if (!inst->EdgeStart()->declaration().is(IfcSchema::IfcVertexPoint::Class()) || !inst->EdgeEnd()->declaration().is(IfcSchema::IfcVertexPoint::Class())) { - Logger::Message(Logger::LOG_ERROR, "GEO", 255, "Only IfcVertexPoints are supported for EdgeStart and -End", inst); + logger_.Message(Logger::LOG_ERROR, "GEO", 255, "Only IfcVertexPoints are supported for EdgeStart and -End", inst); return nullptr; } IfcSchema::IfcPoint* pnt1 = ((IfcSchema::IfcVertexPoint*) inst->EdgeStart())->VertexGeometry(); IfcSchema::IfcPoint* pnt2 = ((IfcSchema::IfcVertexPoint*) inst->EdgeEnd())->VertexGeometry(); if (!pnt1->declaration().is(IfcSchema::IfcCartesianPoint::Class()) || !pnt2->declaration().is(IfcSchema::IfcCartesianPoint::Class())) { - Logger::Message(Logger::LOG_ERROR, "GEO", 256, "Only IfcCartesianPoints are supported for VertexGeometry", inst); + logger_.Message(Logger::LOG_ERROR, "GEO", 256, "Only IfcCartesianPoints are supported for VertexGeometry", inst); return nullptr; } diff --git a/src/ifcgeom/mapping/IfcEllipse.cpp b/src/ifcgeom/mapping/IfcEllipse.cpp index 393320c3a8..182c696327 100644 --- a/src/ifcgeom/mapping/IfcEllipse.cpp +++ b/src/ifcgeom/mapping/IfcEllipse.cpp @@ -26,7 +26,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEllipse* inst) { double y = inst->SemiAxis2() * length_unit_; const double tol = settings_.get().get(); if (x < tol || y < tol) { - Logger::Message(Logger::LOG_ERROR, "GEO", 257, "Radius not greater than zero for:", inst); + logger_.Message(Logger::LOG_ERROR, "GEO", 257, "Radius not greater than zero for:", inst); return nullptr; } diff --git a/src/ifcgeom/mapping/IfcEllipseProfileDef.cpp b/src/ifcgeom/mapping/IfcEllipseProfileDef.cpp index c186110626..5db3d30a6d 100644 --- a/src/ifcgeom/mapping/IfcEllipseProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcEllipseProfileDef.cpp @@ -26,7 +26,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEllipseProfileDef* inst) { double ry = inst->SemiAxis2() * length_unit_; const double tol = settings_.get().get(); if (rx < tol || ry < tol) { - Logger::Message(Logger::LOG_ERROR, "GEO", 258, "Radius not greater than zero for:", inst); + logger_.Message(Logger::LOG_ERROR, "GEO", 258, "Radius not greater than zero for:", inst); return nullptr; } diff --git a/src/ifcgeom/mapping/IfcExtrudedAreaSolid.cpp b/src/ifcgeom/mapping/IfcExtrudedAreaSolid.cpp index 664c6ddbd5..f41ce363b9 100644 --- a/src/ifcgeom/mapping/IfcExtrudedAreaSolid.cpp +++ b/src/ifcgeom/mapping/IfcExtrudedAreaSolid.cpp @@ -27,7 +27,7 @@ using namespace ifcopenshell::geometry; taxonomy::ptr mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolid* inst) { const double height = inst->Depth() * length_unit_; if (height < settings_.get().get()) { - Logger::Message(Logger::LOG_ERROR, "GEO", 259, "Non-positive extrusion height encountered for:", inst); + logger_.Message(Logger::LOG_ERROR, "GEO", 89, "Non-positive extrusion height encountered for:", inst); #ifndef PERMISSIVE_EXTRUSION return nullptr; #endif diff --git a/src/ifcgeom/mapping/IfcExtrudedAreaSolidTapered.cpp b/src/ifcgeom/mapping/IfcExtrudedAreaSolidTapered.cpp index fcd54fc524..f94bccc812 100644 --- a/src/ifcgeom/mapping/IfcExtrudedAreaSolidTapered.cpp +++ b/src/ifcgeom/mapping/IfcExtrudedAreaSolidTapered.cpp @@ -27,7 +27,7 @@ using namespace ifcopenshell::geometry; taxonomy::ptr mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolidTapered* inst) { const double height = inst->Depth() * length_unit_; if (height < settings_.get().get()) { - Logger::Message(Logger::LOG_ERROR, "GEO", 260, "Non-positive extrusion height encountered for:", inst); + logger_.Message(Logger::LOG_ERROR, "GEO", 89, "Non-positive extrusion height encountered for:", inst); return nullptr; } diff --git a/src/ifcgeom/mapping/IfcGradientCurve.cpp b/src/ifcgeom/mapping/IfcGradientCurve.cpp index 91ecff6ded..cf631407a0 100644 --- a/src/ifcgeom/mapping/IfcGradientCurve.cpp +++ b/src/ifcgeom/mapping/IfcGradientCurve.cpp @@ -26,7 +26,7 @@ using namespace ifcopenshell::geometry; taxonomy::ptr mapping::map_impl(const IfcSchema::IfcGradientCurve* inst) { if (!inst->BaseCurve()->as()) - Logger::Warning("GEO", 261, "Expected IfcGradientCurve.BaseCurve to be IfcCompositeCurve", inst); // CT 4.1.7.1.1.2 + logger_.Warning("GEO", 261, "Expected IfcGradientCurve.BaseCurve to be IfcCompositeCurve", inst); // CT 4.1.7.1.1.2 auto segments = inst->Segments(); @@ -41,11 +41,11 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcGradientCurve* inst) { // for this reason, a dynamic cast is used and if crv is a function_item it is added to the span spans.push_back(fi); } else { - Logger::Error("UNS", 14, "Unsupported"); + logger_.Error("UNS", 14, "Unsupported"); return nullptr; } } else { - Logger::Error("UNS", 15, "Unsupported"); + logger_.Error("UNS", 15, "Unsupported"); return nullptr; } } @@ -73,7 +73,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcGradientCurve* inst) { // check to see if there is valid overlap of the horizontal and vertical domains if (!(0 < gradient_function->length())) { - Logger::Error("GEO", 262, "IfcGradientCurve does not have a common domain with BaseCurve"); + logger_.Error("GEO", 262, "IfcGradientCurve does not have a common domain with BaseCurve"); gradient_function = nullptr; // not valid } diff --git a/src/ifcgeom/mapping/IfcHalfSpaceSolid.cpp b/src/ifcgeom/mapping/IfcHalfSpaceSolid.cpp index 2989269219..7b300feac3 100644 --- a/src/ifcgeom/mapping/IfcHalfSpaceSolid.cpp +++ b/src/ifcgeom/mapping/IfcHalfSpaceSolid.cpp @@ -24,7 +24,7 @@ using namespace ifcopenshell::geometry; taxonomy::ptr mapping::map_impl(const IfcSchema::IfcHalfSpaceSolid* inst) { IfcSchema::IfcSurface* surface = inst->BaseSurface(); if (!surface->declaration().is(IfcSchema::IfcPlane::Class())) { - Logger::Message(Logger::LOG_ERROR, "UNS", 16, "Unsupported BaseSurface:", surface); + logger_.Message(Logger::LOG_ERROR, "UNS", 16, "Unsupported BaseSurface:", surface); return nullptr; } auto p = taxonomy::make(); diff --git a/src/ifcgeom/mapping/IfcIShapeProfileDef.cpp b/src/ifcgeom/mapping/IfcIShapeProfileDef.cpp index 0b74f0886e..62e24a8e0d 100644 --- a/src/ifcgeom/mapping/IfcIShapeProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcIShapeProfileDef.cpp @@ -81,7 +81,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcIShapeProfileDef* inst) { const double tol = settings_.get().get(); if (x1 < tol || x2 < tol || y < tol || d1 < tol || ft1 < tol || ft2 < tol) { - Logger::Message(Logger::LOG_NOTICE, "GEO", 264, "Skipping zero sized profile:", inst); + logger_.Message(Logger::LOG_NOTICE, "GEO", 264, "Skipping zero sized profile:", inst); return nullptr; } diff --git a/src/ifcgeom/mapping/IfcIndexedPolyCurve.cpp b/src/ifcgeom/mapping/IfcIndexedPolyCurve.cpp index d05ccb8a58..c264d08ae6 100644 --- a/src/ifcgeom/mapping/IfcIndexedPolyCurve.cpp +++ b/src/ifcgeom/mapping/IfcIndexedPolyCurve.cpp @@ -90,7 +90,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcIndexedPolyCurve* inst) { e->basis = circ; loop->children.push_back(e); } else { - Logger::Warning("GEO", 263, "Ignoring segment on", inst); + logger_.Warning("GEO", 263, "Ignoring segment on", inst); } } else { throw IfcParse::IfcException("Unexpected IfcIndexedPolyCurve segment of type " + segment->as()->declaration().name()); diff --git a/src/ifcgeom/mapping/IfcLShapeProfileDef.cpp b/src/ifcgeom/mapping/IfcLShapeProfileDef.cpp index d440ac3ef2..44d2838dcd 100644 --- a/src/ifcgeom/mapping/IfcLShapeProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcLShapeProfileDef.cpp @@ -45,7 +45,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcLShapeProfileDef* inst) { const double tol = settings_.get().get(); if ( x < tol || y < tol || d < tol) { - Logger::Message(Logger::LOG_NOTICE, "GEO", 265, "Skipping zero sized profile:", inst); + logger_.Message(Logger::LOG_NOTICE, "GEO", 265, "Skipping zero sized profile:", inst); return nullptr; } @@ -77,7 +77,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcLShapeProfileDef* inst) { const double det = a1*b2 - a2*b1; if (std::fabs(det) < 1.e-5) { - Logger::Message(Logger::LOG_NOTICE, "GEO", 266, "Legs do not intersect for:", inst); + logger_.Message(Logger::LOG_NOTICE, "GEO", 266, "Legs do not intersect for:", inst); return nullptr; } diff --git a/src/ifcgeom/mapping/IfcObjectPlacement.cpp b/src/ifcgeom/mapping/IfcObjectPlacement.cpp index 921e6d60a6..f307fdb2e8 100644 --- a/src/ifcgeom/mapping/IfcObjectPlacement.cpp +++ b/src/ifcgeom/mapping/IfcObjectPlacement.cpp @@ -54,7 +54,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcObjectPlacement* inst) { } } #else - Logger::Warning("GEO", 267, "Using --site-local-placement or --building-local-placement on IFC4.2 might have issues"); + logger_.Warning("GEO", 267, "Using --site-local-placement or --building-local-placement on IFC4.2 might have issues"); #endif } } @@ -127,7 +127,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcObjectPlacement* inst) { if (fallback) { auto mapped_fallback = taxonomy::cast(map(fallback)); if (!result->ccomponents().isApprox(mapped_fallback->ccomponents())) { - Logger::Warning("GEO", 268, "Computed placement differs from fallback", inst); + logger_.Warning("GEO", 268, "Computed placement differs from fallback", inst); } } @@ -135,7 +135,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcObjectPlacement* inst) { auto abs_det = std::abs(result->ccomponents().determinant()); if (abs_det < 1.e-7) { - Logger::Warning("GEO", 269, "Ignoring singular matrix:", inst); + logger_.Warning("GEO", 269, "Ignoring singular matrix:", inst); return nullptr; } diff --git a/src/ifcgeom/mapping/IfcOffsetCurveByDistance.cpp b/src/ifcgeom/mapping/IfcOffsetCurveByDistance.cpp index 324e6ac0fb..376c7d028d 100644 --- a/src/ifcgeom/mapping/IfcOffsetCurveByDistance.cpp +++ b/src/ifcgeom/mapping/IfcOffsetCurveByDistance.cpp @@ -33,7 +33,7 @@ using namespace ifcopenshell::geometry; taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst) { auto offset_values = inst->OffsetValues(); if (offset_values->size() == 0) { - Logger::Error("GEO", 270, "IfcOffsetCurveByDistances must have at least one offset value"); + logger_.Error("GEO", 270, "IfcOffsetCurveByDistances must have at least one offset value"); } auto first_offset_value = *(offset_values->begin()); @@ -56,7 +56,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst auto basis_curve_fn = taxonomy::dcast(map(basis_curve)); if (!basis_curve_fn) { // Only implement on alignment curves - Logger::Warning("GEO", 271, "IfcOffsetCurveByDistances is only implemented for BasisCurves curves based on taxonomy::function_item", inst); + logger_.Warning("GEO", 271, "IfcOffsetCurveByDistances is only implemented for BasisCurves curves based on taxonomy::function_item", inst); return nullptr; } @@ -73,7 +73,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst first_distance *= length_unit_; if (first_distance < 0.0) { - Logger::Warning("GEO", 272, "IfcOffsetCurveByDistance first offset value is before the start of the curve."); + logger_.Warning("GEO", 272, "IfcOffsetCurveByDistance first offset value is before the start of the curve."); } if(0.0 < first_distance) @@ -110,7 +110,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst if (dn < dp) // next is before previous { - Logger::Warning("GEO", 273, "IfcOffsetCurveByDistance offset value is out of bounds."); + logger_.Warning("GEO", 273, "IfcOffsetCurveByDistance offset value is out of bounds."); continue; } diff --git a/src/ifcgeom/mapping/IfcOpenCrossProfileDef.cpp b/src/ifcgeom/mapping/IfcOpenCrossProfileDef.cpp index c32d20c295..b4433a481a 100644 --- a/src/ifcgeom/mapping/IfcOpenCrossProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcOpenCrossProfileDef.cpp @@ -32,7 +32,7 @@ const double PI = boost::math::constants::pi(); taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOpenCrossProfileDef* inst) { if (inst->ProfileType() != IfcSchema::IfcProfileTypeEnum::IfcProfileType_CURVE) { - Logger::Warning("GEO", 274, "Expected IfcOpenCrossProfileDef.ProfileType to be CURVE", inst); + logger_.Warning("GEO", 274, "Expected IfcOpenCrossProfileDef.ProfileType to be CURVE", inst); return nullptr; } @@ -55,7 +55,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOpenCrossProfileDef* inst) { auto angles = inst->Slopes(); // these are actually angles, but the attribute is called Slopes if (widths.size() != angles.size()) { - Logger::Warning("GEO", 275, "Expected Widths and Slopes to be equal length, but got " + std::to_string(widths.size()) + " and " + std::to_string(angles.size()) + " respectively", inst); + logger_.Warning("GEO", 275, "Expected Widths and Slopes to be equal length, but got " + std::to_string(widths.size()) + " and " + std::to_string(angles.size()) + " respectively", inst); return nullptr; } diff --git a/src/ifcgeom/mapping/IfcPolyLoop.cpp b/src/ifcgeom/mapping/IfcPolyLoop.cpp index d4225c33a0..baa26923c6 100644 --- a/src/ifcgeom/mapping/IfcPolyLoop.cpp +++ b/src/ifcgeom/mapping/IfcPolyLoop.cpp @@ -36,7 +36,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolyLoop* inst) { // A loop should consist of at least three vertices int original_count = polygon.size(); if (original_count < 3) { - Logger::Message(Logger::LOG_WARNING, "GEO", 278, "Not enough edges for:", inst); + logger_.Message(Logger::LOG_WARNING, "GEO", 278, "Not enough edges for:", inst); return nullptr; } @@ -45,17 +45,17 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolyLoop* inst) { auto previous_size = polygon.size(); remove_duplicate_points_from_loop(polygon, true, eps); if (polygon.size() != previous_size) { - Logger::Warning("GEO", 279, "Removed " + std::to_string(previous_size - polygon.size()) + " (near) duplicate points from:", inst); + logger_.Warning("GEO", 279, "Removed " + std::to_string(previous_size - polygon.size()) + " (near) duplicate points from:", inst); } int count = polygon.size(); if (original_count - count != 0) { std::stringstream ss; ss << (original_count - count) << " edges removed for:"; - Logger::Message(Logger::LOG_WARNING, "GEO", 280, ss.str(), inst); + logger_.Message(Logger::LOG_WARNING, "GEO", 280, ss.str(), inst); } if (count < 3) { - Logger::Message(Logger::LOG_WARNING, "GEO", 281, "Not enough edges for:", inst); + logger_.Message(Logger::LOG_WARNING, "GEO", 281, "Not enough edges for:", inst); return nullptr; } diff --git a/src/ifcgeom/mapping/IfcPolyline.cpp b/src/ifcgeom/mapping/IfcPolyline.cpp index 87a1644b77..54d03daf8d 100644 --- a/src/ifcgeom/mapping/IfcPolyline.cpp +++ b/src/ifcgeom/mapping/IfcPolyline.cpp @@ -44,12 +44,12 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolyline* inst) { auto previous_size = polygon.size(); remove_duplicate_points_from_loop(polygon, closed_by_proximity, eps); if (polygon.size() != previous_size) { - Logger::Warning("GEO", 276, "Removed " + std::to_string(previous_size - polygon.size()) + " (near) duplicate points from:", inst); + logger_.Warning("GEO", 276, "Removed " + std::to_string(previous_size - polygon.size()) + " (near) duplicate points from:", inst); } if (polygon.size() < 2) { // We somehow need to signal we fail this curve on purpose not to trigger an error. - Logger::Warning("GEO", 277, "Invalid polyline with " + std::to_string(polygon.size()) + " points:", inst); + logger_.Warning("GEO", 277, "Invalid polyline with " + std::to_string(polygon.size()) + " points:", inst); return nullptr; } diff --git a/src/ifcgeom/mapping/IfcRectangleHollowProfileDef.cpp b/src/ifcgeom/mapping/IfcRectangleHollowProfileDef.cpp index 80a738ef99..888522c8b3 100644 --- a/src/ifcgeom/mapping/IfcRectangleHollowProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcRectangleHollowProfileDef.cpp @@ -37,7 +37,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRectangleHollowProfileDef* i const double tol = settings_.get().get(); if (x < tol || y < tol) { - Logger::Message(Logger::LOG_NOTICE, "GEO", 282, "Skipping zero sized profile:", inst); + logger_.Message(Logger::LOG_NOTICE, "GEO", 282, "Skipping zero sized profile:", inst); return nullptr; } diff --git a/src/ifcgeom/mapping/IfcRectangleProfileDef.cpp b/src/ifcgeom/mapping/IfcRectangleProfileDef.cpp index e04ae0c1f5..b4ca163c2b 100644 --- a/src/ifcgeom/mapping/IfcRectangleProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcRectangleProfileDef.cpp @@ -30,7 +30,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRectangleProfileDef* inst) { const double tol = settings_.get().get(); if (x < tol || y < tol) { - Logger::Message(Logger::LOG_NOTICE, "GEO", 283, "Skipping zero sized profile:", inst); + logger_.Message(Logger::LOG_NOTICE, "GEO", 283, "Skipping zero sized profile:", inst); return nullptr; } diff --git a/src/ifcgeom/mapping/IfcRoundedRectangleProfileDef.cpp b/src/ifcgeom/mapping/IfcRoundedRectangleProfileDef.cpp index c35b868334..f272e3c3a6 100644 --- a/src/ifcgeom/mapping/IfcRoundedRectangleProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcRoundedRectangleProfileDef.cpp @@ -31,7 +31,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRoundedRectangleProfileDef* const double tol = settings_.get().get(); if (x < tol || y < tol) { - Logger::Message(Logger::LOG_NOTICE, "GEO", 284, "Skipping zero sized profile:", inst); + logger_.Message(Logger::LOG_NOTICE, "GEO", 284, "Skipping zero sized profile:", inst); return nullptr; } diff --git a/src/ifcgeom/mapping/IfcSectionedSolidHorizontal.cpp b/src/ifcgeom/mapping/IfcSectionedSolidHorizontal.cpp index 28ef4da190..41f4b7bc94 100644 --- a/src/ifcgeom/mapping/IfcSectionedSolidHorizontal.cpp +++ b/src/ifcgeom/mapping/IfcSectionedSolidHorizontal.cpp @@ -34,7 +34,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSectionedSolidHorizontal* in auto fn = taxonomy::dcast(dir); if (!fn) { // Only implement on alignment curves - Logger::Warning("GEO", 285, "IfcSectionedSolidHorizontal is only implemented for Directrix curves based on taxonomy::function_item", inst); + logger_.Warning("GEO", 285, "IfcSectionedSolidHorizontal is only implemented for Directrix curves based on taxonomy::function_item", inst); return nullptr; } @@ -74,11 +74,11 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSectionedSolidHorizontal* in profile_rotations.push_back(rot); } if (faces.size() != profile_offsets.size()) { - Logger::Warning("GEO", 286, "Expected CrossSections and CrossSectionPositions to be equal length, but got " + std::to_string(faces.size()) + " and " + std::to_string(profile_offsets.size()) + " respectively", inst); + logger_.Warning("GEO", 286, "Expected CrossSections and CrossSectionPositions to be equal length, but got " + std::to_string(faces.size()) + " and " + std::to_string(profile_offsets.size()) + " respectively", inst); return nullptr; } if (faces.size() < 2) { - Logger::Warning("GEO", 287, "Expected at least two cross sections, but got " + std::to_string(faces.size()), inst); + logger_.Warning("GEO", 287, "Expected at least two cross sections, but got " + std::to_string(faces.size()), inst); return nullptr; } diff --git a/src/ifcgeom/mapping/IfcSectionedSurface.cpp b/src/ifcgeom/mapping/IfcSectionedSurface.cpp index 997ecacadd..0089fbe69d 100644 --- a/src/ifcgeom/mapping/IfcSectionedSurface.cpp +++ b/src/ifcgeom/mapping/IfcSectionedSurface.cpp @@ -34,7 +34,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSectionedSurface* inst) { auto fn = taxonomy::dcast(dir); if (!fn) { // Only implement on alignment curves - Logger::Warning("GEO", 288, "IfcSectionedSurface is only implemented for Directrix curves based on taxonomy::function_item", inst); + logger_.Warning("GEO", 288, "IfcSectionedSurface is only implemented for Directrix curves based on taxonomy::function_item", inst); return nullptr; } @@ -79,11 +79,11 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSectionedSurface* inst) { return nullptr; #endif if (faces.size() != profile_offsets.size()) { - Logger::Warning("GEO", 289, "Expected CrossSections and CrossSectionPositions to be equal length, but got " + std::to_string(faces.size()) + " and " + std::to_string(profile_offsets.size()) + " respectively", inst); + logger_.Warning("GEO", 289, "Expected CrossSections and CrossSectionPositions to be equal length, but got " + std::to_string(faces.size()) + " and " + std::to_string(profile_offsets.size()) + " respectively", inst); return nullptr; } if (faces.size() < 2) { - Logger::Warning("GEO", 290, "Expected at least two cross sections, but got " + std::to_string(faces.size()), inst); + logger_.Warning("GEO", 290, "Expected at least two cross sections, but got " + std::to_string(faces.size()), inst); return nullptr; } diff --git a/src/ifcgeom/mapping/IfcSegmentedReferenceCurve.cpp b/src/ifcgeom/mapping/IfcSegmentedReferenceCurve.cpp index d02adb2a96..967ef4d1e9 100644 --- a/src/ifcgeom/mapping/IfcSegmentedReferenceCurve.cpp +++ b/src/ifcgeom/mapping/IfcSegmentedReferenceCurve.cpp @@ -27,7 +27,7 @@ using namespace ifcopenshell::geometry; taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSegmentedReferenceCurve* inst) { if (!inst->BaseCurve()->as()) - Logger::Warning("GEO", 291, "Expected IfcSegmentedReferenceCurve.BaseCurve to be IfcGradient", inst); // CT 4.1.7.1.1.3 + logger_.Warning("GEO", 291, "Expected IfcSegmentedReferenceCurve.BaseCurve to be IfcGradient", inst); // CT 4.1.7.1.1.3 auto segments = inst->Segments(); @@ -41,11 +41,11 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSegmentedReferenceCurve* ins // for this reason, a dynamic cast is used and if crv is a function_item it is added to the span spans.push_back(fi); } else { - Logger::Error("UNS", 17, "Unsupported"); + logger_.Error("UNS", 17, "Unsupported"); return nullptr; } } else { - Logger::Error("UNS", 18, "Unsupported"); + logger_.Error("UNS", 18, "Unsupported"); return nullptr; } } @@ -67,7 +67,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSegmentedReferenceCurve* ins auto cant_function = taxonomy::make(gradient, cant, inst); if (!(0 < cant_function->length())) { - Logger::Error("GEO", 292, "IfcSegmentedReferenceCurve does not have a common domain with BaseCurve"); + logger_.Error("GEO", 292, "IfcSegmentedReferenceCurve does not have a common domain with BaseCurve"); cant_function = nullptr; } return cant_function; diff --git a/src/ifcgeom/mapping/IfcSweptDiskSolid.cpp b/src/ifcgeom/mapping/IfcSweptDiskSolid.cpp index b2f52a0818..0aede08d39 100644 --- a/src/ifcgeom/mapping/IfcSweptDiskSolid.cpp +++ b/src/ifcgeom/mapping/IfcSweptDiskSolid.cpp @@ -1,4 +1,4 @@ -/******************************************************************************** +/******************************************************************************** * * * This file is part of IfcOpenShell. * * * @@ -62,7 +62,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSweptDiskSolid* inst) { sp = inst->StartParam(); ep = inst->EndParam(); } catch (const IfcParse::IfcException& e) { - Logger::Warning("GEO", 293, e); + logger_.Warning("GEO", 293, e); } #endif diff --git a/src/ifcgeom/mapping/IfcTShapeProfileDef.cpp b/src/ifcgeom/mapping/IfcTShapeProfileDef.cpp index dffea7d1b2..c79ece4bf1 100644 --- a/src/ifcgeom/mapping/IfcTShapeProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcTShapeProfileDef.cpp @@ -40,7 +40,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTShapeProfileDef* inst) { const double tol = settings_.get().get(); if (x < tol || y < tol || d1 < tol || d2 < tol) { - Logger::Message(Logger::LOG_NOTICE, "GEO", 296, "Skipping zero sized profile:", inst); + logger_.Message(Logger::LOG_NOTICE, "GEO", 296, "Skipping zero sized profile:", inst); return nullptr; } @@ -88,7 +88,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTShapeProfileDef* inst) { const double det = a1*b2 - a2*b1; if (std::fabs(det) < 1.e-5) { - Logger::Message(Logger::LOG_NOTICE, "GEO", 297, "Web and flange do not intersect for:", inst); + logger_.Message(Logger::LOG_NOTICE, "GEO", 297, "Web and flange do not intersect for:", inst); return nullptr; } diff --git a/src/ifcgeom/mapping/IfcTrapeziumProfileDef.cpp b/src/ifcgeom/mapping/IfcTrapeziumProfileDef.cpp index 00735c8cae..615805713d 100644 --- a/src/ifcgeom/mapping/IfcTrapeziumProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcTrapeziumProfileDef.cpp @@ -36,7 +36,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTrapeziumProfileDef* inst) { const double tol = settings_.get().get(); if (x1 < tol || w < tol || y < tol) { - Logger::Message(Logger::LOG_NOTICE, "GEO", 294, "Skipping zero sized profile:", inst); + logger_.Message(Logger::LOG_NOTICE, "GEO", 294, "Skipping zero sized profile:", inst); return nullptr; } diff --git a/src/ifcgeom/mapping/IfcTrimmedCurve.cpp b/src/ifcgeom/mapping/IfcTrimmedCurve.cpp index 6baac7ebc1..c94944d5b7 100644 --- a/src/ifcgeom/mapping/IfcTrimmedCurve.cpp +++ b/src/ifcgeom/mapping/IfcTrimmedCurve.cpp @@ -76,7 +76,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTrimmedCurve* inst) { bool trim_cartesian_failed = !trim_cartesian; if (trim_cartesian) { if ((pnts[0]->ccomponents() - pnts[1]->ccomponents()).norm() < (2 * tol)) { - Logger::Message(Logger::LOG_WARNING, "GEO", 295, "Skipping segment with length below tolerance level:", inst); + logger_.Message(Logger::LOG_WARNING, "GEO", 295, "Skipping segment with length below tolerance level:", inst); return nullptr; } tc->start = pnts[0]; diff --git a/src/ifcgeom/mapping/IfcUShapeProfileDef.cpp b/src/ifcgeom/mapping/IfcUShapeProfileDef.cpp index f2b0be59c1..607d6dbaed 100644 --- a/src/ifcgeom/mapping/IfcUShapeProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcUShapeProfileDef.cpp @@ -54,7 +54,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcUShapeProfileDef* inst) { const double tol = settings_.get().get(); if (x < tol || y < tol || d1 < tol || d2 < tol) { - Logger::Message(Logger::LOG_NOTICE, "GEO", 298, "Skipping zero sized profile:", inst); + logger_.Message(Logger::LOG_NOTICE, "GEO", 298, "Skipping zero sized profile:", inst); return nullptr; } diff --git a/src/ifcgeom/mapping/IfcZShapeProfileDef.cpp b/src/ifcgeom/mapping/IfcZShapeProfileDef.cpp index 8d8c430973..be5bd06073 100644 --- a/src/ifcgeom/mapping/IfcZShapeProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcZShapeProfileDef.cpp @@ -45,7 +45,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcZShapeProfileDef* inst) { const double tol = settings_.get().get(); if (x < tol || y < tol || dx < tol || dy < tol) { - Logger::Message(Logger::LOG_NOTICE, "GEO", 299, "Skipping zero sized profile:", inst); + logger_.Message(Logger::LOG_NOTICE, "GEO", 299, "Skipping zero sized profile:", inst); return nullptr; } diff --git a/src/ifcgeom/mapping/mapping.cpp b/src/ifcgeom/mapping/mapping.cpp index f2abe22aad..56df064c49 100644 --- a/src/ifcgeom/mapping/mapping.cpp +++ b/src/ifcgeom/mapping/mapping.cpp @@ -1,4 +1,4 @@ -/******************************************************************************** +/******************************************************************************** * * * This file is part of IfcOpenShell. * * * @@ -32,8 +32,8 @@ using namespace IfcGeom; namespace { struct POSTFIX_SCHEMA(factory_t) { - abstract_mapping* operator()(IfcParse::IfcFile* file, Settings& settings) const { - ifcopenshell::geometry::POSTFIX_SCHEMA(mapping)* m = new ifcopenshell::geometry::POSTFIX_SCHEMA(mapping)(file, settings); + abstract_mapping* operator()(IfcParse::IfcFile* file, Settings& settings, Logger& logger) const { + ifcopenshell::geometry::POSTFIX_SCHEMA(mapping)* m = new ifcopenshell::geometry::POSTFIX_SCHEMA(mapping)(file, settings, logger); return m; } }; @@ -83,7 +83,7 @@ IfcSchema::IfcProduct::list::ptr mapping::products_represented_by(const IfcSchem try { target = taxonomy::cast(map(item->MappingTarget())); } catch (const std::exception& e) { - Logger::Error("GEO", 300, e); + logger_.Error("GEO", 300, e); continue; } if (!target->is_identity()) { @@ -332,7 +332,7 @@ const IfcUtil::IfcBaseEntity* mapping::get_single_material_association(const Ifc try { associated_material = (*associated_materials->begin())->RelatingMaterial(); } catch(IfcParse::IfcException& e) { - Logger::Error("GEO", 301, e.what()); + logger_.Error("GEO", 301, e.what()); } if (associated_material) { @@ -344,7 +344,7 @@ const IfcUtil::IfcBaseEntity* mapping::get_single_material_association(const Ifc IfcSchema::IfcMaterialLayerSet* layerset; if (auto *m = associated_material->as()) { if (m->get("ForLayerSet").isNull()) { - Logger::Warning("GEO", 302, "Missing ForLayerSet for:", m); + logger_.Warning("GEO", 302, "Missing ForLayerSet for:", m); return nullptr; } layerset = m->ForLayerSet(); @@ -363,7 +363,7 @@ const IfcUtil::IfcBaseEntity* mapping::get_single_material_association(const Ifc IfcSchema::IfcMaterialProfileSet* profileset; if (auto* m = associated_material->as()) { if (m->get("ForProfileSet").isNull()) { - Logger::Warning("GEO", 303, "Missing ForProfileSet for:", m); + logger_.Warning("GEO", 303, "Missing ForProfileSet for:", m); return nullptr; } profileset = m->ForProfileSet(); @@ -408,7 +408,7 @@ IfcSchema::IfcRepresentation* mapping::representation_mapped_to(const IfcSchema: try { target = taxonomy::cast(map(mapped_item->MappingTarget())); } catch (const std::exception& e) { - Logger::Error("GEO", 304, e); + logger_.Error("GEO", 304, e); } if (target && target->is_identity()) { IfcSchema::IfcRepresentationMap* rmap = mapped_item->MappingSource(); @@ -571,7 +571,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcMaterial* material) { failed_on_purpose_.insert(material); return nullptr; } - Logger::Warning("UNS", 19, "Skipping unsupported material style for material: ", material); + logger_.Warning("UNS", 19, "Skipping unsupported material style for material: ", material); } } @@ -605,7 +605,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcStyledItem* inst) { if (style == nullptr) { // E.g. IfcCurveStyle is skipped as unsupported. - Logger::Warning("GEO", 305, "Only IfcSurfaceStyle is supported, couldn't find it in IfcStyledItem: ", inst); + logger_.Warning("GEO", 305, "Only IfcSurfaceStyle is supported, couldn't find it in IfcStyledItem: ", inst); failed_on_purpose_.insert(inst); return nullptr; } @@ -700,7 +700,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSurfaceStyle* style) { taxonomy::ptr mapping::map(const IfcBaseInterface* inst) { if (inst == nullptr) { - Logger::Error("GEO", 306, "Warning nullptr passed to map() function"); + logger_.Error("GEO", 306, "Warning nullptr passed to map() function"); return nullptr; } auto iden = inst->as()->identity(); @@ -727,7 +727,7 @@ taxonomy::ptr mapping::map(const IfcBaseInterface* inst) { cache_.insert({iden, item}); } } else if (!matched) { - Logger::Message(Logger::LOG_ERROR, "GEO", 307, "No operation defined for:", inst); + logger_.Message(Logger::LOG_ERROR, "GEO", 307, "No operation defined for:", inst); } return item; } @@ -833,10 +833,10 @@ void mapping::initialize_units_() { auto* project = *projects->begin(); unit_assignment = project->UnitsInContext(); } else { - Logger::Warning("GEO", 308, "Not a single project or context in file"); + logger_.Warning("GEO", 308, "Not a single project or context in file"); } if (unit_assignment == nullptr) { - Logger::Warning("GEO", 309, "Unable to detect unit information"); + logger_.Warning("GEO", 309, "Unable to detect unit information"); return; } @@ -845,7 +845,7 @@ void mapping::initialize_units_() { try { auto units = unit_assignment->Units(); if (!units || !units->size()) { - Logger::Warning("GEO", 310, "No unit information found"); + logger_.Warning("GEO", 310, "No unit information found"); } else { for (auto it = units->begin(); it != units->end(); ++it) { IfcSchema::IfcUnit* base = *it; @@ -882,15 +882,15 @@ void mapping::initialize_units_() { } catch (const IfcParse::IfcException& ex) { std::stringstream ss; ss << "Failed to determine unit information '" << ex.what() << "'"; - Logger::Message(Logger::LOG_ERROR, "GEO", 311, ss.str()); + logger_.Message(Logger::LOG_ERROR, "GEO", 311, ss.str()); } if (!length_unit_encountered) { - Logger::Warning("GEO", 312, "No length unit encountered"); + logger_.Warning("GEO", 312, "No length unit encountered"); } if (!angle_unit_encountered) { - Logger::Warning("GEO", 313, "No plane angle unit encountered"); + logger_.Warning("GEO", 313, "No plane angle unit encountered"); } // @todo move to a more descriptive function @@ -907,7 +907,7 @@ void mapping::initialize_units_() { if (vs.size() == 3) { offset_and_rotation_ *= Eigen::Affine3d(Eigen::Translation3d(vs[0], vs[1], vs[2])).matrix(); } else { - Logger::Error("SYS", 31, "Expected 3 values for model-offset setting"); + logger_.Error("SYS", 31, "Expected 3 values for model-offset setting"); } } @@ -920,7 +920,7 @@ void mapping::initialize_units_() { m4 << m3; offset_and_rotation_ *= m4; } else { - Logger::Error("SYS", 32, "Expected 4 values for model-rotation setting"); + logger_.Error("SYS", 32, "Expected 4 values for model-rotation setting"); } } } @@ -970,7 +970,7 @@ void mapping::initialize_settings() { if (any_precision_encountered) { if (lowest_precision_encountered < 1.e-7) { - Logger::Message(Logger::LOG_WARNING, "SYS", 33, "Precision lower than 0.0000001 meter not enforced"); + logger_.Message(Logger::LOG_WARNING, "SYS", 33, "Precision lower than 0.0000001 meter not enforced"); precision_to_set = 1.e-7; } else { precision_to_set = lowest_precision_encountered; @@ -1007,7 +1007,7 @@ bool mapping::get_layerset_information(const IfcUtil::IfcBaseInterface* p, layer IfcSchema::IfcRepresentation* body_representation = find_representation(product, "Body"); if (!body_representation) { - Logger::Warning("GEO", 314, "No body representation for product", product); + logger_.Warning("GEO", 314, "No body representation for product", product); return false; } @@ -1021,7 +1021,7 @@ bool mapping::get_layerset_information(const IfcUtil::IfcBaseInterface* p, layer IfcSchema::IfcRepresentation* axis_representation = find_representation(product, "Axis"); if (!axis_representation) { - Logger::Message(Logger::LOG_WARNING, "GEO", 315, "No axis representation for:", product); + logger_.Message(Logger::LOG_WARNING, "GEO", 315, "No axis representation for:", product); return false; } @@ -1090,7 +1090,7 @@ bool mapping::get_layerset_information(const IfcUtil::IfcBaseInterface* p, layer IfcSchema::IfcExtrudedAreaSolid::list::ptr extrusions = IfcParse::traverse(body_representation)->as(); if (extrusions->size() != 1) { - Logger::Message(Logger::LOG_WARNING, "GEO", 316, "No single extrusion found in body representation for:", product); + logger_.Message(Logger::LOG_WARNING, "GEO", 316, "No single extrusion found in body representation for:", product); return false; } @@ -1105,7 +1105,7 @@ bool mapping::get_layerset_information(const IfcUtil::IfcBaseInterface* p, layer if (has_position) { auto m4 = taxonomy::cast(map(extrusion->Position())); if (!m4) { - Logger::Message(Logger::LOG_ERROR, "GEO", 317, "Failed to convert placement for extrusion of:", product); + logger_.Message(Logger::LOG_ERROR, "GEO", 317, "Failed to convert placement for extrusion of:", product); return false; } else { extrusion_position = m4; @@ -1115,7 +1115,7 @@ bool mapping::get_layerset_information(const IfcUtil::IfcBaseInterface* p, layer taxonomy::direction3::ptr extrusion_direction = taxonomy::cast(map(extrusion->ExtrudedDirection())); if (!extrusion_direction) { - Logger::Message(Logger::LOG_ERROR, "GEO", 318, "Failed to convert direction for extrusion of:", product); + logger_.Message(Logger::LOG_ERROR, "GEO", 318, "Failed to convert direction for extrusion of:", product); return false; } @@ -1189,12 +1189,12 @@ void mapping::addRepresentationsFromContextIds(IfcSchema::IfcRepresentation::lis try { context = file_->instance_by_id(context_id)->as(); } catch (IfcParse::IfcException& e) { - Logger::Error("GEO", 319, e); + logger_.Error("GEO", 319, e); continue; } if (!context) { - Logger::Error("GEO", 320, "Failed to process context ID " + std::to_string(context_id)); + logger_.Error("GEO", 320, "Failed to process context ID " + std::to_string(context_id)); continue; } @@ -1243,14 +1243,14 @@ void mapping::addRepresentationsFromDefaultContexts(IfcSchema::IfcRepresentation boost::to_lower(context_type); if (allowed_context_types.find(context_type) == allowed_context_types.end()) { - Logger::Warning("GEO", 321, std::string("ContextType '") + *context->ContextType() + "' not allowed:", context); + logger_.Warning("GEO", 321, std::string("ContextType '") + *context->ContextType() + "' not allowed:", context); } if (context_types.find(context_type) != context_types.end()) { filtered_contexts->push(context); } } } catch (const std::exception& e) { - Logger::Error("GEO", 322, e); + logger_.Error("GEO", 322, e); } } @@ -1280,7 +1280,7 @@ void mapping::addRepresentationsFromDefaultContexts(IfcSchema::IfcRepresentation } if (representations->size() == 0) { - Logger::Warning("GEO", 323, "No representations encountered in relevant contexts, using all"); + logger_.Warning("GEO", 323, "No representations encountered in relevant contexts, using all"); representations->push(file_->instances_by_type()); } } @@ -1326,7 +1326,7 @@ IfcUtil::IfcBaseEntity* mapping::representation_of(const IfcUtil::IfcBaseEntity* intersection_no_box->push(r); } if (intersection_no_box->size() > 1) { - Logger::Warning("GEO", 324, "Multiple applicable representations found for element, selecting arbitrary"); + logger_.Warning("GEO", 324, "Multiple applicable representations found for element, selecting arbitrary"); } if (intersection_no_box->size()) { return (*intersection_no_box->begin())->as(); diff --git a/src/ifcgeom/mapping/mapping.h b/src/ifcgeom/mapping/mapping.h index d79cb582ec..2ddfadd728 100644 --- a/src/ifcgeom/mapping/mapping.h +++ b/src/ifcgeom/mapping/mapping.h @@ -67,19 +67,19 @@ namespace geometry { } } } catch (const std::exception& e) { - Logger::Message(Logger::LOG_ERROR, "GEO", 325, std::string(e.what()) + "\nFailed to convert:", inst); + logger_.Message(Logger::LOG_ERROR, "GEO", 325, std::string(e.what()) + "\nFailed to convert:", inst); } } else if (failed_on_purpose_.find(inst) == failed_on_purpose_.end()) { - Logger::Message(Logger::LOG_ERROR, "GEO", 326, "Failed to convert:", inst); + logger_.Message(Logger::LOG_ERROR, "GEO", 326, "Failed to convert:", inst); } } catch (const std::exception& e) { - Logger::Message(Logger::LOG_ERROR, "GEO", 327, std::string(e.what()) + "\nFailed to convert:", inst); + logger_.Message(Logger::LOG_ERROR, "GEO", 327, std::string(e.what()) + "\nFailed to convert:", inst); } } } const IfcSchema::IfcStyledItem* find_style(const IfcSchema::IfcRepresentationItem*); public: - POSTFIX_SCHEMA(mapping)(IfcParse::IfcFile* file, Settings& settings) : abstract_mapping(settings), file_(file), placement_rel_to_type_(0), placement_rel_to_instance_(0) { + POSTFIX_SCHEMA(mapping)(IfcParse::IfcFile* file, Settings& settings, Logger& logger = Logger::Root()) : abstract_mapping(settings, logger), file_(file), placement_rel_to_type_(0), placement_rel_to_instance_(0) { initialize_units_(); } virtual ifcopenshell::geometry::taxonomy::ptr map(const IfcUtil::IfcBaseInterface*); @@ -153,4 +153,4 @@ namespace geometry { } -#endif \ No newline at end of file +#endif diff --git a/src/ifcgeom/taxonomy.cpp b/src/ifcgeom/taxonomy.cpp index 0184c03e9f..eaf67986f5 100644 --- a/src/ifcgeom/taxonomy.cpp +++ b/src/ifcgeom/taxonomy.cpp @@ -861,7 +861,7 @@ boost::optional ifcopenshell::geometry::taxonomy::loop_to_fu spans.emplace_back(taxonomy::make(l, fn)); } else if (edge_->start.which() == 1 && edge_->end.which() == 1) { if (edge_->basis && edge_->basis->kind() != LINE) { - Logger::Message(Logger::Severity::LOG_WARNING, "UNS", 20, "Basis curve not supported - edge is treated as a straight line edge"); + Logger::Root().Message(Logger::Severity::LOG_WARNING, "UNS", 20, "Basis curve not supported - edge is treated as a straight line edge"); } const auto& s = boost::get(edge_->start)->ccomponents(); const auto& e = boost::get(edge_->end)->ccomponents(); @@ -876,7 +876,7 @@ boost::optional ifcopenshell::geometry::taxonomy::loop_to_fu }; spans.emplace_back(taxonomy::make(l, fn)); } else { - Logger::Message(Logger::Severity::LOG_ERROR, "UNS", 21, "Basis curve not supported"); + Logger::Root().Message(Logger::Severity::LOG_ERROR, "UNS", 21, "Basis curve not supported"); return boost::none; } } diff --git a/src/ifcgeomserver/IfcGeomServer.cpp b/src/ifcgeomserver/IfcGeomServer.cpp index b01e4ed992..ab255a78ad 100644 --- a/src/ifcgeomserver/IfcGeomServer.cpp +++ b/src/ifcgeomserver/IfcGeomServer.cpp @@ -641,7 +641,7 @@ int main () { } case GET_LOG: { GetLog gl; gl.read(std::cin); - WriteLog(Logger::GetLog()).write(std::cout); + WriteLog(Logger::Root().GetLog()).write(std::cout); continue; } case BYE: { diff --git a/src/ifcopenshell-python/ifcopenshell/__init__.py b/src/ifcopenshell-python/ifcopenshell/__init__.py index 7d247c6fab..2c93e8175e 100644 --- a/src/ifcopenshell-python/ifcopenshell/__init__.py +++ b/src/ifcopenshell-python/ifcopenshell/__init__.py @@ -95,6 +95,7 @@ from .entity_instance import entity_instance, register_schema_attributes from .file import file, rocksdb_lazy_instance from .file import file as _file from .sql import sqlite, sqlite_entity +from .ifcopenshell_wrapper import get_log, logger # explicitly specify available imported symbols # (it's a requirement for a typed library) @@ -389,4 +390,3 @@ def convert_path_to_rocksdb(ifcspf_path: Union[Path, str], rocksdb_path: Union[P version_core = ifcopenshell_wrapper.version() __version__ = version = "0.0.0" -get_log = ifcopenshell_wrapper.get_log diff --git a/src/ifcopenshell-python/ifcopenshell/geom/main.py b/src/ifcopenshell-python/ifcopenshell/geom/main.py index 9c36e4b933..574d19d904 100644 --- a/src/ifcopenshell-python/ifcopenshell/geom/main.py +++ b/src/ifcopenshell-python/ifcopenshell/geom/main.py @@ -461,6 +461,7 @@ def create_shape( inst: entity_instance, repr: Optional[entity_instance] = None, geometry_library: GEOMETRY_LIBRARY = "opencascade", + logger: Optional[ifcopenshell.logger] = None, ) -> Union[ShapeType, ShapeElementType, ifcopenshell_wrapper.Transformation, utils.shape_tuple, TopoDS.TopoDS_Shape]: """ Returns a geometric interpretation of the IFC entity instance @@ -507,7 +508,7 @@ def create_shape( return wrap_shape_creation( settings, ifcopenshell_wrapper.create_shape( - settings, inst.wrapped_data, repr.wrapped_data if repr is not None else None, geometry_library + settings, inst.wrapped_data, repr.wrapped_data if repr is not None else None, geometry_library, *(filter(None, (logger,))) ), ) diff --git a/src/ifcopenshell-python/test/fixtures/ColumnPSetsOfSets.ifc b/src/ifcopenshell-python/test/fixtures/ColumnPSetsOfSets.ifc index 26394a29b3..f124bb79db 100644 --- a/src/ifcopenshell-python/test/fixtures/ColumnPSetsOfSets.ifc +++ b/src/ifcopenshell-python/test/fixtures/ColumnPSetsOfSets.ifc @@ -2,7 +2,7 @@ ISO-10303-21; HEADER; FILE_DESCRIPTION(('ViewDefinition [CoordinationView]','RevitIdentifiers [ContentGUID: a0df3484-2dab-42c5-b806-8c10d313bee0, VersionGUID: 658c1394-f3a4-43d1-9b3c-eee44a0cd67a, NumberOfSaves: 2]','CoordinateReference [CoordinateBase: Shared Coordinates]'),'2;1'); FILE_NAME('Column_4x3.ifc','2025-03-12T13:53:30+00:00',(''),(''),'ODA SDAI 24.12','Autodesk Revit 25.4.0.32 (ENG) - IFC 25.4.0.32',''); -FILE_SCHEMA(('IFC4X3_ADD2')); +FILE_SCHEMA(('IFC2X3')); ENDSEC; DATA; #1=IFCORGANIZATION($,'Autodesk Revit 2025 (ENG)',$,$,$); diff --git a/src/ifcopenshell-python/test/test_create_shape.py b/src/ifcopenshell-python/test/test_create_shape.py index dfcb68c7be..bda6767295 100644 --- a/src/ifcopenshell-python/test/test_create_shape.py +++ b/src/ifcopenshell-python/test/test_create_shape.py @@ -216,6 +216,26 @@ def test_iterator(): assert iterator.initialize() +def test_logging(): + logger = ifcopenshell.logger() + logger.OutputFormat(logger.FMT_INMEMORY) + settings = ifcopenshell.geom.settings() + f = ifcopenshell.open(fn) + col = f.by_type("IfcColumn")[0] + _ = ifcopenshell.geom.create_shape(settings, col, logger=logger) + + num_log_items = len(list(logger)) + col.Representation.Representations[0].Items[0].MappingSource.MappedRepresentation.Items[0].Depth *= -1.0 + + with pytest.raises(RuntimeError): + _ = ifcopenshell.geom.create_shape(settings, col, logger=logger) + new_items = list(logger)[num_log_items:] + + assert ("GEO089", "Non-positive extrusion height encountered for:") in [ + (msg.code, msg.message) for msg in new_items + ] + + if __name__ == "__main__": import pytest diff --git a/src/ifcparse/IfcAlignmentHelper.cpp b/src/ifcparse/IfcAlignmentHelper.cpp index 39f4dd2457..5edba1022c 100644 --- a/src/ifcparse/IfcAlignmentHelper.cpp +++ b/src/ifcparse/IfcAlignmentHelper.cpp @@ -412,7 +412,7 @@ std::pair mapAlign } else if (cant) { result = mapAlignmentCantSegment(cant); } else { - Logger::Error("VAL", 8, std::string("Unexpected IfcAlignmentSegment subtype encountered")); + Logger::Root().Error("VAL", 8, std::string("Unexpected IfcAlignmentSegment subtype encountered")); } return result; } @@ -661,9 +661,9 @@ std::pair mapAlign result.first = curve_segment; } else if (type == Ifc4x3_add2::IfcAlignmentHorizontalSegmentTypeEnum::IfcAlignmentHorizontalSegmentType_VIENNESEBEND) { - Logger::Warning("UNS", 22, std::string("mapping of AlignmentHorizontalSegmentType VIENNESEBEND not supported")); + Logger::Root().Warning("UNS", 22, std::string("mapping of AlignmentHorizontalSegmentType VIENNESEBEND not supported")); } else { - Logger::Error("VAL", 9, std::string("unexpected AlignmentHorizontalSegmentType encountered")); + Logger::Root().Error("VAL", 9, std::string("unexpected AlignmentHorizontalSegmentType encountered")); } return result; @@ -732,7 +732,7 @@ std::pair mapAlign result.first = curve_segment; } else if (type == Ifc4x3_add2::IfcAlignmentVerticalSegmentTypeEnum::IfcAlignmentVerticalSegmentType_CLOTHOID) { - Logger::Warning("UNS", 23, std::string("mapping of AlignmentVerticalSegmentType CLOTHOID not supported")); + Logger::Root().Warning("UNS", 23, std::string("mapping of AlignmentVerticalSegmentType CLOTHOID not supported")); } else if (type == Ifc4x3_add2::IfcAlignmentVerticalSegmentTypeEnum::IfcAlignmentVerticalSegmentType_CIRCULARARC) { auto start_angle = atan(start_gradient); auto end_angle = atan(end_gradient); @@ -760,7 +760,7 @@ std::pair mapAlign result.first = curve_segment; } else { - Logger::Error("VAL", 10, std::string("unexpected AlignmentVerticalSegmentType encountered")); + Logger::Root().Error("VAL", 10, std::string("unexpected AlignmentVerticalSegmentType encountered")); } return result; @@ -770,21 +770,21 @@ std::pair mapAlign std::pair result(nullptr, nullptr); auto type = segment->PredefinedType(); if (type == Ifc4x3_add2::IfcAlignmentCantSegmentTypeEnum::IfcAlignmentCantSegmentType_BLOSSCURVE) { - Logger::Warning("UNS", 24, std::string("mapping of AlignmentCantSegmentType BLOSSCURVE not supported")); + Logger::Root().Warning("UNS", 24, std::string("mapping of AlignmentCantSegmentType BLOSSCURVE not supported")); } else if (type == Ifc4x3_add2::IfcAlignmentCantSegmentTypeEnum::IfcAlignmentCantSegmentType_CONSTANTCANT) { - Logger::Warning("UNS", 25, std::string("mapping of AlignmentCantSegmentType CONSTANTCANT not supported")); + Logger::Root().Warning("UNS", 25, std::string("mapping of AlignmentCantSegmentType CONSTANTCANT not supported")); } else if (type == Ifc4x3_add2::IfcAlignmentCantSegmentTypeEnum::IfcAlignmentCantSegmentType_COSINECURVE) { - Logger::Warning("UNS", 26, std::string("mapping of AlignmentCantSegmentType COSINECURVE not supported")); + Logger::Root().Warning("UNS", 26, std::string("mapping of AlignmentCantSegmentType COSINECURVE not supported")); } else if (type == Ifc4x3_add2::IfcAlignmentCantSegmentTypeEnum::IfcAlignmentCantSegmentType_HELMERTCURVE) { - Logger::Warning("UNS", 27, std::string("mapping of AlignmentCantSegmentType HELMERTCURVE not supported")); + Logger::Root().Warning("UNS", 27, std::string("mapping of AlignmentCantSegmentType HELMERTCURVE not supported")); } else if (type == Ifc4x3_add2::IfcAlignmentCantSegmentTypeEnum::IfcAlignmentCantSegmentType_LINEARTRANSITION) { - Logger::Warning("UNS", 28, std::string("mapping of AlignmentCantSegmentType LINEARTRANSTION not supported")); + Logger::Root().Warning("UNS", 28, std::string("mapping of AlignmentCantSegmentType LINEARTRANSTION not supported")); } else if (type == Ifc4x3_add2::IfcAlignmentCantSegmentTypeEnum::IfcAlignmentCantSegmentType_SINECURVE) { - Logger::Warning("UNS", 29, std::string("mapping of AlignmentCantSegmentType SINECURVE not supported")); + Logger::Root().Warning("UNS", 29, std::string("mapping of AlignmentCantSegmentType SINECURVE not supported")); } else if (type == Ifc4x3_add2::IfcAlignmentCantSegmentTypeEnum::IfcAlignmentCantSegmentType_VIENNESEBEND) { - Logger::Warning("UNS", 30, std::string("mapping of AlignmentCantSegmentType VIENNESEBEND not supported")); + Logger::Root().Warning("UNS", 30, std::string("mapping of AlignmentCantSegmentType VIENNESEBEND not supported")); } else { - Logger::Error("VAL", 11, std::string("unexpected AlignmentCantSegmentType encountered")); + Logger::Root().Error("VAL", 11, std::string("unexpected AlignmentCantSegmentType encountered")); } return result; } diff --git a/src/ifcparse/IfcCharacterDecoder.cpp b/src/ifcparse/IfcCharacterDecoder.cpp index 6cf1e66004..10606a9cf6 100644 --- a/src/ifcparse/IfcCharacterDecoder.cpp +++ b/src/ifcparse/IfcCharacterDecoder.cpp @@ -137,7 +137,7 @@ namespace { parse_state += PAGE; } else if (IS_HEXADECIMAL(current_char) && EXPECTS_HEX(parse_state)) { if (IS_LOWERCASE_HEX(current_char)) { - Logger::Warning("SYN", 2, "Lowercase hexadecimal character '" + std::string(1, current_char) + + Logger::Root().Warning("SYN", 2, "Lowercase hexadecimal character '" + std::string(1, current_char) + "' found at offset " + std::to_string(stream_.tell()) + ". It is recommended to use uppercase for hexadecimal."); } diff --git a/src/ifcparse/IfcFile.cpp b/src/ifcparse/IfcFile.cpp index 36fb61366d..7b45430088 100644 --- a/src/ifcparse/IfcFile.cpp +++ b/src/ifcparse/IfcFile.cpp @@ -72,10 +72,10 @@ namespace { try { fn(EnumerationReference(decl->as_enumeration_type(), decl->as_enumeration_type()->lookup_enum_offset(s))); } catch (IfcParse::IfcException& e) { - Logger::Error("VAL", 12, "An enumeration literal '" + s + "' is not valid for type '" + decl->name() + "' at offset " + std::to_string(t.startPos)); + Logger::Root().Error("VAL", 12, "An enumeration literal '" + s + "' is not valid for type '" + decl->name() + "' at offset " + std::to_string(t.startPos)); } } else { - Logger::Error("VAL", 13, "An enumeration literal '" + s + "' is not expected at attribute index '" + std::to_string(attribute_id) + "' at offset " + std::to_string(t.startPos)); + Logger::Root().Error("VAL", 13, "An enumeration literal '" + s + "' is not expected at attribute index '" + std::to_string(attribute_id) + "' at offset " + std::to_string(t.startPos)); } } else if (t.type == IfcParse::Token_FLOAT) { fn(IfcParse::TokenFunc::asFloat(t)); @@ -194,7 +194,7 @@ namespace { } }, aggregate_storage); - Logger::Error("VAL", 14, "Inconsistent aggregate valuation while attempting to append " + std::string(typeid(decltype(v)).name()) + " to an aggregate of " + current); + Logger::Root().Error("VAL", 14, "Inconsistent aggregate valuation while attempting to append " + std::string(typeid(decltype(v)).name()) + " to an aggregate of " + current); // @todo boolean -> logical upgrade // wait a second... there are no aggregate of bool / logical in the schema.. @@ -213,7 +213,7 @@ namespace { } } else { // @todo would be cool if we can trace this back to file offset - Logger::Error("UNS", 31, std::string("Aggregates of ") + typeid(decltype(v)).name() + " are not supported in the IfcOpenShell parser"); + Logger::Root().Error("UNS", 31, std::string("Aggregates of ") + typeid(decltype(v)).name() + " are not supported in the IfcOpenShell parser"); } }; @@ -263,9 +263,9 @@ IfcEntityInstanceData IfcParse::parse_context::construct(boost::optional { size_t expected = expected_size ? *expected_size : parameter_types.size(); if (decl != nullptr && decl->schema() == &Header_section_schema::get_schema()) { - Logger::Warning("VAL", 15, "Expected " + std::to_string(expected) + " attribute values, found " + std::to_string(tokens_.size()) + " for header entity " + decl->name()); + Logger::Root().Warning("VAL", 15, "Expected " + std::to_string(expected) + " attribute values, found " + std::to_string(tokens_.size()) + " for header entity " + decl->name()); } else { - Logger::Warning("VAL", 16, "Expected " + std::to_string(expected) + " attribute values, found " + std::to_string(tokens_.size()) + (name ? std::string(" for instance #" + std::to_string(*name)) : std::string(""))); + Logger::Root().Warning("VAL", 16, "Expected " + std::to_string(expected) + " attribute values, found " + std::to_string(tokens_.size()) + (name ? std::string(" for instance #" + std::to_string(*name)) : std::string(""))); } } @@ -719,13 +719,13 @@ std::optionaldeclaration_by_name(TokenFunc::asStringRef(token_stream_[2])); } catch (const IfcException& ex) { - Logger::Message(Logger::LOG_ERROR, "SYN", 3, std::string(ex.what()) + " at offset " + std::to_string(token_stream_[2].startPos)); + Logger::Root().Message(Logger::LOG_ERROR, "SYN", 3, std::string(ex.what()) + " at offset " + std::to_string(token_stream_[2].startPos)); current_id = 0; goto advance; } if (entity_type->as_entity() == nullptr) { - Logger::Message(Logger::LOG_ERROR, "SYN", 4, "Non entity type " + entity_type->name() + " at offset " + std::to_string(token_stream_[2].startPos)); + Logger::Root().Message(Logger::LOG_ERROR, "SYN", 4, "Non entity type " + entity_type->name() + " at offset " + std::to_string(token_stream_[2].startPos)); goto advance; } @@ -744,7 +744,7 @@ std::optionalas_entity(), ps, -1); } catch (const IfcInvalidTokenException& e) { good_ = file_open_status::INVALID_SYNTAX; - Logger::Error("SYN", 5, e); + Logger::Root().Error("SYN", 5, e); break; } @@ -753,7 +753,7 @@ std::optionalNext(); } catch (const IfcException& e) { - Logger::Message(Logger::LOG_ERROR, "SYN", 6, std::string(e.what()) + ". Parsing terminated"); + Logger::Root().Message(Logger::LOG_ERROR, "SYN", 6, std::string(e.what()) + ". Parsing terminated"); } catch (...) { - Logger::Message(Logger::LOG_ERROR, "SYN", 7, "Parsing terminated"); + Logger::Root().Message(Logger::LOG_ERROR, "SYN", 7, "Parsing terminated"); } if (!lexer_->stream->eof() && next_token.type == Token_NONE) { diff --git a/src/ifcparse/IfcGlobalId.cpp b/src/ifcparse/IfcGlobalId.cpp index bf016026ae..af2e4893f5 100644 --- a/src/ifcparse/IfcGlobalId.cpp +++ b/src/ifcparse/IfcGlobalId.cpp @@ -111,7 +111,7 @@ IfcParse::IfcGlobalId::IfcGlobalId() { boost::uuids::uuid test_uuid; std::copy(test_vector.begin(), test_vector.end(), test_uuid.begin()); if (uuid_data_ != test_uuid) { - Logger::Message(Logger::LOG_ERROR, "SYS", 34, "Internal error generating GlobalId"); + Logger::Root().Message(Logger::LOG_ERROR, "SYS", 34, "Internal error generating GlobalId"); } #endif } @@ -130,7 +130,7 @@ IfcParse::IfcGlobalId::IfcGlobalId(const std::string& string) #ifndef NDEBUG const std::string test_string = compress(&uuid_data_.data[0]); if (string_data_ != test_string) { - Logger::Message(Logger::LOG_ERROR, "SYS", 35, "Internal error generating GlobalId"); + Logger::Root().Message(Logger::LOG_ERROR, "SYS", 35, "Internal error generating GlobalId"); } #endif } diff --git a/src/ifcparse/IfcHierarchyHelper.cpp b/src/ifcparse/IfcHierarchyHelper.cpp index 864c332af5..cc3b198e91 100644 --- a/src/ifcparse/IfcHierarchyHelper.cpp +++ b/src/ifcparse/IfcHierarchyHelper.cpp @@ -159,7 +159,7 @@ void IfcHierarchyHelper::relatePlacements(typename Schema::IfcProduct* p if (local_place != parent->ObjectPlacement()) { local_place->setPlacementRelTo(parent->ObjectPlacement()); } else { - Logger::Notice("SYN", 8, "Placement cannot be relative to self"); + Logger::Root().Notice("SYN", 8, "Placement cannot be relative to self"); } } } diff --git a/src/ifcparse/IfcHierarchyHelper.h b/src/ifcparse/IfcHierarchyHelper.h index 67bdb5a187..e397f1f89a 100644 --- a/src/ifcparse/IfcHierarchyHelper.h +++ b/src/ifcparse/IfcHierarchyHelper.h @@ -454,9 +454,9 @@ class IFC_PARSE_API IfcHierarchyHelper : public IfcParse::IfcFile { break; } } catch (std::exception& e) { - Logger::Error("SYN", 9, e); + Logger::Root().Error("SYN", 9, e); } catch (...) { - Logger::Error("SYN", 10, "Unknown error in addRelatedObject()"); + Logger::Root().Error("SYN", 10, "Unknown error in addRelatedObject()"); } } if (!found) { diff --git a/src/ifcparse/IfcLogger.cpp b/src/ifcparse/IfcLogger.cpp index 1bf26da9e6..2146146098 100644 --- a/src/ifcparse/IfcLogger.cpp +++ b/src/ifcparse/IfcLogger.cpp @@ -31,9 +31,8 @@ #include #include #include -#include -static my_thread_local const IfcUtil::IfcBaseClass* current_product_; +static my_thread_local std::map current_products_; namespace { @@ -134,6 +133,24 @@ void json_message(T& out, const IfcUtil::IfcBaseClass* current_product, Logger:: } } // namespace +Logger& Logger::Root() { + static Logger logger; + return logger; +} + +const IfcUtil::IfcBaseClass* Logger::current_product() const { + auto it = current_products_.find(this); + return it == current_products_.end() ? nullptr : it->second; +} + +void Logger::current_product(const IfcUtil::IfcBaseClass* product) { + if (product) { + current_products_[this] = product; + } else { + current_products_.erase(this); + } +} + void Logger::SetProduct(boost::optional product) { if (verbosity_ <= LOG_DEBUG && product) { Message(LOG_DEBUG, "SYS", 3, "Begin processing", *product); @@ -142,7 +159,7 @@ void Logger::SetProduct(boost::optional product) { PrintPerformanceStats(); performance_statistics_.clear(); } - current_product_ = product.get_value_or(nullptr); + current_product(product.get_value_or(nullptr)); } void Logger::SetOutput(std::ostream* stream1, std::ostream* stream2) { @@ -168,8 +185,7 @@ void Logger::Message(Logger::Severity type, const char (&code_prefix)[4], uint16 return; } - static std::mutex mtx; - std::lock_guard lock(mtx); + std::lock_guard lock(mutex_); const std::string code = format_code(code_prefix, code_number); if (type == LOG_PERF) { @@ -188,18 +204,21 @@ void Logger::Message(Logger::Severity type, const char (&code_prefix)[4], uint16 if (type > max_severity_) { max_severity_ = type; } - if (((log2_ != nullptr) || (wlog2_ != nullptr))) { + + if (format_ == FMT_INMEMORY) { + log_messages_.emplace_back(type, code_prefix, code_number, message, instance); + } else if (((log2_ != nullptr) || (wlog2_ != nullptr))) { if (format_ == FMT_PLAIN) { if (log2_ != nullptr) { - plain_text_message(*log2_, current_product_, type, code, message, instance); + plain_text_message(*log2_, current_product(), type, code, message, instance); } else if (wlog2_ != nullptr) { - plain_text_message(*wlog2_, current_product_, type, code, message, instance); + plain_text_message(*wlog2_, current_product(), type, code, message, instance); } } else if (format_ == FMT_JSON) { if (log2_ != nullptr) { - json_message(*log2_, current_product_, type, code, message, instance); + json_message(*log2_, current_product(), type, code, message, instance); } else if (wlog2_ != nullptr) { - json_message(*wlog2_, current_product_, type, code, message, instance); + json_message(*wlog2_, current_product(), type, code, message, instance); } } } @@ -258,22 +277,9 @@ void Logger::PrintPerformanceStats() { } void Logger::Verbosity(Logger::Severity severity) { verbosity_ = severity; } -Logger::Severity Logger::Verbosity() { return verbosity_; } +Logger::Severity Logger::Verbosity() const { return verbosity_; } -Logger::Severity Logger::MaxSeverity() { return max_severity_; } +Logger::Severity Logger::MaxSeverity() const { return max_severity_; } void Logger::OutputFormat(Format format) { format_ = format; } -Logger::Format Logger::OutputFormat() { return format_; } - -std::ostream* Logger::log1_ = 0; -std::ostream* Logger::log2_ = 0; -std::wostream* Logger::wlog1_ = 0; -std::wostream* Logger::wlog2_ = 0; -std::stringstream Logger::log_stream_; -Logger::Severity Logger::verbosity_ = Logger::LOG_NOTICE; -Logger::Severity Logger::max_severity_ = Logger::LOG_NOTICE; -Logger::Format Logger::format_ = Logger::FMT_PLAIN; -boost::optional Logger::first_timepoint_; -std::map Logger::performance_statistics_; -std::map Logger::performance_signal_start_; -bool Logger::print_perf_stats_on_element_ = false; +Logger::Format Logger::OutputFormat() const { return format_; } diff --git a/src/ifcparse/IfcLogger.h b/src/ifcparse/IfcLogger.h index 72f8573db8..ac5a817d5a 100644 --- a/src/ifcparse/IfcLogger.h +++ b/src/ifcparse/IfcLogger.h @@ -28,9 +28,29 @@ #include #include #include +#include #include #include +class IFC_PARSE_API log_message { + public: + char code[7]; + int severity; + std::string message, instance; + + log_message(int severity, const char (&code_prefix)[4], uint16_t code_number, const std::string& message, const IfcUtil::IfcBaseInterface* inst = 0) + : severity(severity) + , message(message) + { + snprintf(code, 7, "%s%03u", code_prefix, code_number); + if (inst) { + std::ostringstream oss; + inst->data().toString(nullptr, nullptr, 0, oss, true); + instance = oss.str(); + } + } +}; + class IFC_PARSE_API Logger { public: typedef enum { @@ -40,76 +60,92 @@ class IFC_PARSE_API Logger { LOG_WARNING, LOG_ERROR } Severity; + typedef enum { FMT_PLAIN, - FMT_JSON + FMT_JSON, + FMT_INMEMORY } Format; private: + std::vector log_messages_; + // To both stream variants need to exist at runtime or should this be a // template argument of Logger or controlled using preprocessor directives? - static std::ostream* log1_; - static std::ostream* log2_; + std::ostream* log1_ = nullptr; + std::ostream* log2_ = nullptr; - static std::wostream* wlog1_; - static std::wostream* wlog2_; + std::wostream* wlog1_ = nullptr; + std::wostream* wlog2_ = nullptr; - static std::stringstream log_stream_; + std::stringstream log_stream_; - static Severity verbosity_; - static Format format_; - static Severity max_severity_; + Severity verbosity_ = LOG_NOTICE; + Format format_ = FMT_PLAIN; + Severity max_severity_ = LOG_NOTICE; - static boost::optional first_timepoint_; - static std::map performance_statistics_; - static std::map performance_signal_start_; + boost::optional first_timepoint_; + std::map performance_statistics_; + std::map performance_signal_start_; - static bool print_perf_stats_on_element_; + bool print_perf_stats_on_element_ = false; + std::mutex mutex_; + + const IfcUtil::IfcBaseClass* current_product() const; + void current_product(const IfcUtil::IfcBaseClass* product); public: - static void SetProduct(boost::optional product); + Logger() = default; + Logger(const Logger&) = delete; + Logger& operator=(const Logger&) = delete; + + static Logger& Root(); + + void SetProduct(boost::optional product); /// Determines to what stream respectively progress and errors are logged - static void SetOutput(std::wostream* stream1, std::wostream* stream2); + void SetOutput(std::wostream* stream1, std::wostream* stream2); /// Determines to what stream respectively progress and errors are logged - static void SetOutput(std::ostream* stream1, std::ostream* stream2); + void SetOutput(std::ostream* stream1, std::ostream* stream2); /// Determines the types of log messages to get logged - static void Verbosity(Severity severity); - static Severity Verbosity(); - static Severity MaxSeverity(); + void Verbosity(Severity severity); + Severity Verbosity() const; + Severity MaxSeverity() const; /// Determines output format: plain text or sequence of JSON objects - static void OutputFormat(Format format); - static Format OutputFormat(); + void OutputFormat(Format format); + Format OutputFormat() const; /// Log a message to the output stream - static void Message(Severity type, const char (&code_prefix)[4], uint16_t code_number, const std::string& message, const IfcUtil::IfcBaseInterface* instance = 0); - static void Message(Severity type, const char (&code_prefix)[4], uint16_t code_number, const std::exception& exception, const IfcUtil::IfcBaseInterface* instance = 0); + void Message(Severity type, const char (&code_prefix)[4], uint16_t code_number, const std::string& message, const IfcUtil::IfcBaseInterface* instance = 0); + void Message(Severity type, const char (&code_prefix)[4], uint16_t code_number, const std::exception& exception, const IfcUtil::IfcBaseInterface* instance = 0); - static void Notice(const char (&code_prefix)[4], uint16_t code_number, const std::string& message, const IfcUtil::IfcBaseInterface* instance = 0) { Message(LOG_NOTICE, code_prefix, code_number, message, instance); } - static void Warning(const char (&code_prefix)[4], uint16_t code_number, const std::string& message, const IfcUtil::IfcBaseInterface* instance = 0) { Message(LOG_WARNING, code_prefix, code_number, message, instance); } - static void Error(const char (&code_prefix)[4], uint16_t code_number, const std::string& message, const IfcUtil::IfcBaseInterface* instance = 0) { Message(LOG_ERROR, code_prefix, code_number, message, instance); } + void Notice(const char (&code_prefix)[4], uint16_t code_number, const std::string& message, const IfcUtil::IfcBaseInterface* instance = 0) { Message(LOG_NOTICE, code_prefix, code_number, message, instance); } + void Warning(const char (&code_prefix)[4], uint16_t code_number, const std::string& message, const IfcUtil::IfcBaseInterface* instance = 0) { Message(LOG_WARNING, code_prefix, code_number, message, instance); } + void Error(const char (&code_prefix)[4], uint16_t code_number, const std::string& message, const IfcUtil::IfcBaseInterface* instance = 0) { Message(LOG_ERROR, code_prefix, code_number, message, instance); } - static void Notice(const char (&code_prefix)[4], uint16_t code_number, const std::exception& exception, const IfcUtil::IfcBaseInterface* instance = 0) { Message(LOG_NOTICE, code_prefix, code_number, exception, instance); } - static void Warning(const char (&code_prefix)[4], uint16_t code_number, const std::exception& exception, const IfcUtil::IfcBaseInterface* instance = 0) { Message(LOG_WARNING, code_prefix, code_number, exception, instance); } - static void Error(const char (&code_prefix)[4], uint16_t code_number, const std::exception& exception, const IfcUtil::IfcBaseInterface* instance = 0) { Message(LOG_ERROR, code_prefix, code_number, exception, instance); } + void Notice(const char (&code_prefix)[4], uint16_t code_number, const std::exception& exception, const IfcUtil::IfcBaseInterface* instance = 0) { Message(LOG_NOTICE, code_prefix, code_number, exception, instance); } + void Warning(const char (&code_prefix)[4], uint16_t code_number, const std::exception& exception, const IfcUtil::IfcBaseInterface* instance = 0) { Message(LOG_WARNING, code_prefix, code_number, exception, instance); } + void Error(const char (&code_prefix)[4], uint16_t code_number, const std::exception& exception, const IfcUtil::IfcBaseInterface* instance = 0) { Message(LOG_ERROR, code_prefix, code_number, exception, instance); } - static void Status(const std::string& message, bool new_line = true); + void Status(const std::string& message, bool new_line = true); - static void ProgressBar(int progress); - static std::string GetLog(); - static void PrintPerformanceStats(); - static void PrintPerformanceStatsOnElement(bool b) { print_perf_stats_on_element_ = b; } + void ProgressBar(int progress); + std::string GetLog(); + void PrintPerformanceStats(); + void PrintPerformanceStatsOnElement(bool b) { print_perf_stats_on_element_ = b; } + + const std::vector& log_messages() const { return log_messages_; } }; #define PERF(x) \ \ - Logger::Message(Logger::LOG_PERF, "SYS", 1, x); \ + Logger::Root().Message(Logger::LOG_PERF, "SYS", 1, x); \ \ BOOST_SCOPE_EXIT(void) { \ - Logger::Message(Logger::LOG_PERF, "SYS", 2, "done " + std::string(x)); \ + Logger::Root().Message(Logger::LOG_PERF, "SYS", 2, "done " + std::string(x)); \ } \ BOOST_SCOPE_EXIT_END diff --git a/src/ifcparse/IfcParse.cpp b/src/ifcparse/IfcParse.cpp index 83e35a3787..ca10bc4ef1 100644 --- a/src/ifcparse/IfcParse.cpp +++ b/src/ifcparse/IfcParse.cpp @@ -320,7 +320,7 @@ Token IfcParse::GeneralTokenPtr(IfcSpfLexer* lexer, size_t start, const std::str if (first == '#') { token.type = Token_IDENTIFIER; if (!ParseInt(tokenStr.c_str() + 1, token.value_int)) { - Logger::Message(Logger::LOG_ERROR, "SYN", 11, "Token '" + tokenStr + "' at offset " + std::to_string(token.startPos) + " is not valid"); + Logger::Root().Message(Logger::LOG_ERROR, "SYN", 11, "Token '" + tokenStr + "' at offset " + std::to_string(token.startPos) + " is not valid"); token.type = Token_OPERATOR; token.value_char = '$'; } @@ -568,7 +568,7 @@ void IfcParse::impl::in_memory_file_storage::load(boost::optional entity context.push(simple_type_instance); simple_type_instance->file_ = file; } catch (IfcException& e) { - Logger::Message(Logger::LOG_ERROR, "SYN", 12, std::string(e.what()) + " at offset " + std::to_string(next.startPos)); + Logger::Root().Message(Logger::LOG_ERROR, "SYN", 12, std::string(e.what()) + " at offset " + std::to_string(next.startPos)); // #4070 We didn't actually capture an aggregate entry, undo length increment. return_value--; } @@ -663,7 +663,7 @@ void IfcParse::impl::rocks_db_file_storage::unregister_inverse(unsigned id_from, if (it != vals.end()) { vals.erase(it); } else { - Logger::Error("VAL", 17, "Unregistering non-existant inverse #" + std::to_string(id_from) + " on instance #" + std::to_string(inst_id) + " at attribute " + std::to_string(attribute_index)); + Logger::Root().Error("VAL", 17, "Unregistering non-existant inverse #" + std::to_string(id_from) + " on instance #" + std::to_string(inst_id) + " at attribute " + std::to_string(attribute_index)); } s.resize(vals.size() * sizeof(uint32_t)); memcpy(s.data(), vals.data(), s.size()); @@ -1122,7 +1122,7 @@ IfcUtil::IfcBaseClass::set_attribute_value(size_t i, const T& t) { } } } catch (IfcParse::IfcException& e) { - Logger::Error("SYN", 13, e); + Logger::Root().Error("SYN", 13, e); } } @@ -1159,11 +1159,11 @@ IfcUtil::IfcBaseClass::set_attribute_value(size_t i, const T& t) { auto guid = (std::string) new_attribute; auto it = file_->internal_guid_map().find(guid); if (it != file_->internal_guid_map().end()) { - Logger::Warning("VAL", 18, "Duplicate guid " + guid); + Logger::Root().Warning("VAL", 18, "Duplicate guid " + guid); } file_->internal_guid_map().insert({ guid, this }); } catch (IfcParse::IfcException& e) { - Logger::Error("SYN", 14, e); + Logger::Root().Error("SYN", 14, e); } } } @@ -1531,12 +1531,12 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(IfcParse::FileRead schema = IfcParse::schema_by_name(schemas.front()); } catch (const IfcParse::IfcException& e) { good_ = file_open_status::UNSUPPORTED_SCHEMA; - Logger::Error("SYN", 15, e); + Logger::Root().Error("SYN", 15, e); } } if (schema == nullptr) { - Logger::Message(Logger::LOG_ERROR, "UNS", 32, "No support for file schema encountered (" + boost::algorithm::join(schemas, ", ") + ")"); + Logger::Root().Message(Logger::LOG_ERROR, "UNS", 32, "No support for file schema encountered (" + boost::algorithm::join(schemas, ", ") + ")"); return; } @@ -1545,7 +1545,7 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(IfcParse::FileRead InstanceStreamer streamer(schema, tokens); streamer.bypassTypes(typed_to_bypass); - Logger::Status("Scanning file..."); + Logger::Root().Status("Scanning file..."); while (streamer) { @@ -1569,11 +1569,11 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(IfcParse::FileRead if (byguid_.find(guid) != byguid_.end()) { std::stringstream ss; ss << "Instance encountered with non-unique GlobalId " << guid; - Logger::Message(Logger::LOG_WARNING, "SYN", 16, ss.str()); + Logger::Root().Message(Logger::LOG_WARNING, "SYN", 16, ss.str()); } byguid_[guid] = instance; } catch (const IfcException& ex) { - Logger::Message(Logger::LOG_ERROR, "SYN", 17, ex.what()); + Logger::Root().Message(Logger::LOG_ERROR, "SYN", 17, ex.what()); } } @@ -1589,7 +1589,7 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(IfcParse::FileRead if (byid_.find(current_id) != byid_.end()) { std::stringstream ss; ss << "Overwriting instance with name #" << current_id; - Logger::Message(Logger::LOG_WARNING, "SYN", 18, ss.str()); + Logger::Root().Message(Logger::LOG_WARNING, "SYN", 18, ss.str()); } // byidentity_[instance->identity()] = instance; @@ -1612,7 +1612,7 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(IfcParse::FileRead inst->file_ = file; } - Logger::Status("\rDone scanning file "); + Logger::Root().Status("\rDone scanning file "); delete tokens; @@ -1632,7 +1632,7 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(IfcParse::FileRead } auto it = byid_.find(*name); if (it == byid_.end()) { - Logger::Error("SYN", 19, "Instance reference #" + std::to_string(*name) + " used by instance #" + std::to_string(ref) + " at attribute index " + std::to_string(refattr) + " not found at offset " + std::to_string(name->file_offset)); + Logger::Root().Error("SYN", 19, "Instance reference #" + std::to_string(*name) + " used by instance #" + std::to_string(ref) + " at attribute index " + std::to_string(refattr) + " not found at offset " + std::to_string(name->file_offset)); } else { auto* storage = &byid_[p.first.name_]->data(); auto attr_index = p.first.index_; @@ -1649,7 +1649,7 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(IfcParse::FileRead if (storage->has_attribute_value(nullptr, nullptr, 0, attr_index)) { storage->set_attribute_value(nullptr, nullptr, 0, attr_index, it->second); } else { - Logger::Error("SYN", 20, "Duplicate definition for instance reference"); + Logger::Root().Error("SYN", 20, "Duplicate definition for instance reference"); } } } else if (auto* inst = std::get_if(v)) { @@ -1665,7 +1665,7 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(IfcParse::FileRead } auto it = byid_.find(*name); if (it == byid_.end()) { - Logger::Error("SYN", 21, "Instance reference #" + std::to_string(*name) + " used by instance #" + std::to_string(ref) + " at attribute index " + std::to_string(refattr) + " not found at offset " + std::to_string(name->file_offset)); + Logger::Root().Error("SYN", 21, "Instance reference #" + std::to_string(*name) + " used by instance #" + std::to_string(ref) + " at attribute index " + std::to_string(refattr) + " not found at offset " + std::to_string(name->file_offset)); } else { instances->push(it->second); } @@ -1689,7 +1689,7 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(IfcParse::FileRead if (storage->has_attribute_value(nullptr, nullptr, 0, attr_index)) { storage->set_attribute_value(nullptr, nullptr, 0, attr_index, instances); } else { - Logger::Error("SYN", 22, "Duplicate definition for instance reference"); + Logger::Root().Error("SYN", 22, "Duplicate definition for instance reference"); } } else if (auto* vvv = std::get_if>>(&p.second)) { aggregate_of_aggregate_of_instance::ptr instances(new aggregate_of_aggregate_of_instance); @@ -1702,7 +1702,7 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(IfcParse::FileRead } auto it = byid_.find(*name); if (it == byid_.end()) { - Logger::Error("SYN", 23, "Instance reference #" + std::to_string(*name) + " used by instance #" + std::to_string(ref) + " at attribute index " + std::to_string(refattr) + " not found at offset " + std::to_string(name->file_offset)); + Logger::Root().Error("SYN", 23, "Instance reference #" + std::to_string(*name) + " used by instance #" + std::to_string(ref) + " at attribute index " + std::to_string(refattr) + " not found at offset " + std::to_string(name->file_offset)); } else { inner.push_back(it->second); } @@ -1728,12 +1728,12 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(IfcParse::FileRead if (storage->has_attribute_value(nullptr, nullptr, 0, attr_index)) { storage->set_attribute_value(nullptr, nullptr, 0, attr_index, instances); } else { - Logger::Error("SYN", 24, "Duplicate definition for instance reference"); + Logger::Root().Error("SYN", 24, "Duplicate definition for instance reference"); } } } - Logger::Status("Done resolving references"); + Logger::Root().Status("Done resolving references"); } void IfcFile::recalculate_id_counter() { @@ -1893,7 +1893,7 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity, int id) } } } catch (...) { - Logger::Message(Logger::LOG_ERROR, "SYN", 25, "Failed to visit forward references of", entity); + Logger::Root().Message(Logger::LOG_ERROR, "SYN", 25, "Failed to visit forward references of", entity); } // See whether the instance is already part of a file @@ -2066,11 +2066,11 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity, int id) if (byguid_.find(guid) != byguid_.end()) { std::stringstream ss; ss << "Overwriting entity with guid " << guid; - Logger::Message(Logger::LOG_WARNING, "SYN", 26, ss.str()); + Logger::Root().Message(Logger::LOG_WARNING, "SYN", 26, ss.str()); } byguid_.insert({ guid, new_entity }); } catch (const std::exception& ex) { - Logger::Message(Logger::LOG_ERROR, "SYN", 27, ex.what()); + Logger::Root().Message(Logger::LOG_ERROR, "SYN", 27, ex.what()); } } @@ -2243,7 +2243,7 @@ void IfcFile::process_deletion_(IfcUtil::IfcBaseClass* entity) { if (it != byguid_.end()) { byguid_.erase(it); } else { - Logger::Warning("VAL", 19, "GlobalId on rooted instance not encountered in map"); + Logger::Root().Warning("VAL", 19, "GlobalId on rooted instance not encountered in map"); } } diff --git a/src/ifcparse/IfcSpfHeader.cpp b/src/ifcparse/IfcSpfHeader.cpp index 2262b6e9cb..a55319696d 100644 --- a/src/ifcparse/IfcSpfHeader.cpp +++ b/src/ifcparse/IfcSpfHeader.cpp @@ -175,7 +175,7 @@ bool IfcSpfHeader::tryRead() { read(); return true; } catch (const std::exception& e) { - Logger::Error("SYN", 28, e); + Logger::Root().Error("SYN", 28, e); return false; } } diff --git a/src/ifcparse/parse_ifcxml.cpp b/src/ifcparse/parse_ifcxml.cpp index 303f320c98..66ac6a98a8 100644 --- a/src/ifcparse/parse_ifcxml.cpp +++ b/src/ifcparse/parse_ifcxml.cpp @@ -255,7 +255,7 @@ boost::any parse_attribute_value(const IfcParse::parameter_type* ty, const std:: } if (any.empty()) { - Logger::Error("SYN", 29, "Attribute '" + value + "' not successfully parsed"); + Logger::Root().Error("SYN", 29, "Attribute '" + value + "' not successfully parsed"); } return any; @@ -293,7 +293,7 @@ static void end_element(void* user, const xmlChar* tag) { // ignore uos ex:iso_10303_28 (ifc2x3) and ifc:ifcXML (ifc4) if (tagname != "uos" && tagname != "ex:iso_10303_28" && tagname != "ifc:ifcXML" && tagname != "ifcXML") { if (state->stack.empty()) { - Logger::Error("SYN", 30, "Mismatch in parse stack due to previous errors"); + Logger::Root().Error("SYN", 30, "Mismatch in parse stack due to previous errors"); } else { state->stack.pop_back(); } @@ -320,7 +320,7 @@ static void process_characters(void* user, const xmlChar* character, int len) { try { val = parse_attribute_value(pt, txt); } catch (const std::exception& e) { - Logger::Error("SYN", 31, e, state->stack.back().inst()); + Logger::Root().Error("SYN", 31, e, state->stack.back().inst()); } if (!val.empty()) { // type declaration always at idx 0 @@ -348,7 +348,7 @@ static void process_characters(void* user, const xmlChar* character, int len) { } else if (tagname == "documentation") { header.file_description()->setdescription({txt}); } else { - Logger::Error("SYN", 32, "Unrecognized header entry " + tagname); + Logger::Root().Error("SYN", 32, "Unrecognized header entry " + tagname); } } else if (state_type == stack_node::node_instance_attribute) { const auto* pt = state->stack.back().inst()->declaration().as_entity()->attribute_by_index(state->stack.back().idx())->type_of_attribute(); @@ -498,7 +498,7 @@ static void start_element(void* user, const xmlChar* tag, const xmlChar** attrs) }, val); } } else { - Logger::Error("SYN", 33, "Unknown attribute '" + pair.first + "' on entity '" + entity->name() + "' with value '" + pair.second + "'"); + Logger::Root().Error("SYN", 33, "Unknown attribute '" + pair.first + "' on entity '" + entity->name() + "' with value '" + pair.second + "'"); } } } @@ -556,7 +556,7 @@ static void start_element(void* user, const xmlChar* tag, const xmlChar** attrs) try { decl = state->file->schema()->declaration_by_name(tagname_copy); } catch (const std::exception& e) { - Logger::Error("SYN", 34, e); + Logger::Root().Error("SYN", 34, e); } if (decl != nullptr) { auto inst_or_ref = create_instance(decl); @@ -571,7 +571,7 @@ static void start_element(void* user, const xmlChar* tag, const xmlChar** attrs) } else if (state_type == stack_node::node_instance) { const IfcParse::entity* current = state->stack.back().inst()->declaration().as_entity(); if (current == nullptr) { - Logger::Error("SYN", 35, "'" + state->stack.back().inst()->declaration().name() + "' is not an entity, unable to set attribute '" + tagname + "'"); + Logger::Root().Error("SYN", 35, "'" + state->stack.back().inst()->declaration().name() + "' is not an entity, unable to set attribute '" + tagname + "'"); // We need to push something on the stack. Likely there has been some extra indirection that is not understood. state->stack.push_back(state->stack.back()); } else { @@ -582,7 +582,7 @@ static void start_element(void* user, const xmlChar* tag, const xmlChar** attrs) return attr->name() == tagname; }); if (found == inverses.end()) { - Logger::Error("SYN", 36, "Unknown attribute " + tagname); + Logger::Root().Error("SYN", 36, "Unknown attribute " + tagname); state->stack.push_back(state->stack.back()); } else { if ((*found)->bound1() == 0 && (*found)->bound2() == 1) { @@ -595,7 +595,7 @@ static void start_element(void* user, const xmlChar* tag, const xmlChar** attrs) inst->set_attribute_value(idx, state->stack.back().inst()); state->stack.push_back(stack_node::instance(id, inst)); } else { - Logger::Error("SYN", 37, "Unknown attribute " + tagname); + Logger::Root().Error("SYN", 37, "Unknown attribute " + tagname); state->stack.push_back(state->stack.back()); } } else { @@ -642,7 +642,7 @@ static void start_element(void* user, const xmlChar* tag, const xmlChar** attrs) try { decl = state->file->schema()->declaration_by_name(tagname); } catch (const std::exception& e) { - Logger::Error("SYN", 38, e); + Logger::Root().Error("SYN", 38, e); } if (decl == nullptr) { @@ -651,7 +651,7 @@ static void start_element(void* user, const xmlChar* tag, const xmlChar** attrs) const IfcParse::entity* entity = decl->as_entity(); if ((entity == nullptr) && state_type != stack_node::node_instance_attribute) { - Logger::Error("SYN", 39, "Not an entity definition " + tagname); + Logger::Root().Error("SYN", 39, "Not an entity definition " + tagname); goto end; } @@ -665,7 +665,7 @@ static void start_element(void* user, const xmlChar* tag, const xmlChar** attrs) if (inst != nullptr) { inst->set_attribute_value(idx, state->stack.back().inst()); } else { - Logger::Error("SYN", 40, "Internal error, inverse attribute not processed"); + Logger::Root().Error("SYN", 40, "Internal error, inverse attribute not processed"); } } else if (state_type == stack_node::node_instance_attribute) { state->stack.back().inst()->set_attribute_value(state->stack.back().idx(), inst); diff --git a/src/ifcwrap/IfcGeomWrapper.i b/src/ifcwrap/IfcGeomWrapper.i index e992e4beab..a9cf372dc1 100644 --- a/src/ifcwrap/IfcGeomWrapper.i +++ b/src/ifcwrap/IfcGeomWrapper.i @@ -882,10 +882,10 @@ struct ShapeRTTI : public boost::static_visitor } template - static boost::variant helper_fn_create_shape(const std::string& geometry_library, ifcopenshell::geometry::Settings& st, IfcUtil::IfcBaseClass* instance, IfcUtil::IfcBaseClass* representation = 0) { + static boost::variant helper_fn_create_shape(Logger& logger, const std::string& geometry_library, ifcopenshell::geometry::Settings& st, IfcUtil::IfcBaseClass* instance, IfcUtil::IfcBaseClass* representation = 0) { IfcParse::IfcFile* file = instance->file_; - ifcopenshell::geometry::Converter kernel(ifcopenshell::geometry::kernels::construct(file, geometry_library, st), file, st); + ifcopenshell::geometry::Converter kernel(ifcopenshell::geometry::kernels::construct(file, geometry_library, st, logger), file, st, logger); if (typename Schema::IfcProduct* product = instance->as()) { if (representation) { @@ -1064,67 +1064,67 @@ ifcopenshell::geometry::taxonomy::item::ptr try_upcast(PyObject* obj0, swig_type %} %inline %{ - static boost::variant create_shape(ifcopenshell::geometry::Settings& settings, IfcUtil::IfcBaseClass* instance, IfcUtil::IfcBaseClass* representation = 0, const char* const geometry_library="opencascade") { + static boost::variant create_shape(ifcopenshell::geometry::Settings& settings, IfcUtil::IfcBaseClass* instance, IfcUtil::IfcBaseClass* representation = 0, const char* const geometry_library="opencascade", Logger& logger = Logger::Root()) { const std::string& schema_name = instance->declaration().schema()->name(); #ifdef HAS_SCHEMA_2x3 if (schema_name == "IFC2X3") { - return helper_fn_create_shape(geometry_library, settings, instance, representation); + return helper_fn_create_shape(logger, geometry_library, settings, instance, representation); } #endif #ifdef HAS_SCHEMA_4 if (schema_name == "IFC4") { - return helper_fn_create_shape(geometry_library, settings, instance, representation); + return helper_fn_create_shape(logger, geometry_library, settings, instance, representation); } #endif #ifdef HAS_SCHEMA_4x1 if (schema_name == "IFC4X1") { - return helper_fn_create_shape(geometry_library, settings, instance, representation); + return helper_fn_create_shape(logger, geometry_library, settings, instance, representation); } #endif #ifdef HAS_SCHEMA_4x2 if (schema_name == "IFC4X2") { - return helper_fn_create_shape(geometry_library, settings, instance, representation); + return helper_fn_create_shape(logger, geometry_library, settings, instance, representation); } #endif #ifdef HAS_SCHEMA_4x3_rc1 if (schema_name == "IFC4X3_RC1") { - return helper_fn_create_shape(geometry_library, settings, instance, representation); + return helper_fn_create_shape(logger, geometry_library, settings, instance, representation); } #endif #ifdef HAS_SCHEMA_4x3_rc2 if (schema_name == "IFC4X3_RC2") { - return helper_fn_create_shape(geometry_library, settings, instance, representation); + return helper_fn_create_shape(logger, geometry_library, settings, instance, representation); } #endif #ifdef HAS_SCHEMA_4x3_rc3 if (schema_name == "IFC4X3_RC3") { - return helper_fn_create_shape(geometry_library, settings, instance, representation); + return helper_fn_create_shape(logger, geometry_library, settings, instance, representation); } #endif #ifdef HAS_SCHEMA_4x3_rc4 if (schema_name == "IFC4X3_RC4") { - return helper_fn_create_shape(geometry_library, settings, instance, representation); + return helper_fn_create_shape(logger, geometry_library, settings, instance, representation); } #endif #ifdef HAS_SCHEMA_4x3 if (schema_name == "IFC4X3") { - return helper_fn_create_shape(geometry_library, settings, instance, representation); + return helper_fn_create_shape(logger, geometry_library, settings, instance, representation); } #endif #ifdef HAS_SCHEMA_4x3_tc1 if (schema_name == "IFC4X3_TC1") { - return helper_fn_create_shape(geometry_library, settings, instance, representation); + return helper_fn_create_shape(logger, geometry_library, settings, instance, representation); } #endif #ifdef HAS_SCHEMA_4x3_add1 if (schema_name == "IFC4X3_ADD1") { - return helper_fn_create_shape(geometry_library, settings, instance, representation); + return helper_fn_create_shape(logger, geometry_library, settings, instance, representation); } #endif #ifdef HAS_SCHEMA_4x3_add2 if (schema_name == "IFC4X3_ADD2") { - return helper_fn_create_shape(geometry_library, settings, instance, representation); + return helper_fn_create_shape(logger, geometry_library, settings, instance, representation); } #endif diff --git a/src/ifcwrap/IfcParseWrapper.i b/src/ifcwrap/IfcParseWrapper.i index 1bc43b422c..ab750543ef 100644 --- a/src/ifcwrap/IfcParseWrapper.i +++ b/src/ifcwrap/IfcParseWrapper.i @@ -80,6 +80,7 @@ private: %rename("file") IfcFile; %rename("add") addEntity; %rename("remove") removeEntity; +%rename("logger") Logger; class attribute_value_derived {}; %{ @@ -702,6 +703,7 @@ private: %include "../ifcparse/IfcBaseClass.h" %include "../ifcparse/IfcSchema.h" %include "../serializers/RocksDbSerializer.h" +%include "../ifcparse/IfcLogger.h" // The IfcFile* returned by open() is to be freed by SWIG/Python %newobject open; @@ -878,7 +880,7 @@ private: static std::stringstream ifcopenshell_log_stream; %} %init %{ - Logger::SetOutput(0, &ifcopenshell_log_stream); + Logger::Root().SetOutput(0, &ifcopenshell_log_stream); %} %inline %{ std::string get_log() { @@ -887,20 +889,20 @@ private: return log; } void turn_on_detailed_logging() { - Logger::SetOutput(&std::cout, &std::cout); - Logger::Verbosity(Logger::LOG_DEBUG); + Logger::Root().SetOutput(&std::cout, &std::cout); + Logger::Root().Verbosity(Logger::LOG_DEBUG); } void turn_off_detailed_logging() { - Logger::SetOutput(0, &ifcopenshell_log_stream); - Logger::Verbosity(Logger::LOG_WARNING); + Logger::Root().SetOutput(0, &ifcopenshell_log_stream); + Logger::Root().Verbosity(Logger::LOG_WARNING); } void set_log_format_json() { ifcopenshell_log_stream.str(""); - Logger::OutputFormat(Logger::FMT_JSON); + Logger::Root().OutputFormat(Logger::FMT_JSON); } void set_log_format_text() { ifcopenshell_log_stream.str(""); - Logger::OutputFormat(Logger::FMT_PLAIN); + Logger::Root().OutputFormat(Logger::FMT_PLAIN); } %} @@ -1221,4 +1223,28 @@ private: return d; } } - \ No newline at end of file + +%extend Logger { + %pythoncode %{ + def __iter__(self): + return iter(self.log_messages()) + %} +} + +%extend log_message { + std::string severity_string() const { + static const char* const severity_strings[] = {"PERF", "DEBUG", "NOTICE", "WARNING", "ERROR"}; + return severity_strings[(int)$self->severity]; + } + %pythoncode %{ + severity_string = property(severity_string) + def to_tuple(self): + return self.severity_string, self.code, self.message, self.instance + def __eq__(self, other): + return type(self) == type(other) and self.to_tuple() == other.to_tuple() + def __hash__(self): + return hash(self.to_tuple()) + def __repr__(self): + return "" % (self.severity_string, self.code, self.message) + %} +} diff --git a/src/ifcwrap/utils/type_conversion.i b/src/ifcwrap/utils/type_conversion.i index 3eacf55fac..4b47cac55b 100644 --- a/src/ifcwrap/utils/type_conversion.i +++ b/src/ifcwrap/utils/type_conversion.i @@ -169,6 +169,7 @@ PyObject* pythonize(const IfcParse::inverse_attribute* t) { return SWIG_NewPointerObj(SWIG_as_voidptr(t), SWIGTYPE_p_IfcParse__inverse_attribute, 0); } PyObject* pythonize(const IfcParse::entity* t) { return SWIG_NewPointerObj(SWIG_as_voidptr(t), SWIGTYPE_p_IfcParse__entity, 0); } PyObject* pythonize(const IfcParse::declaration* t) { return SWIG_NewPointerObj(SWIG_as_voidptr(t), declaration_type_to_swig(t), 0); } + PyObject* pythonize(const log_message& t) { return SWIG_NewPointerObj(SWIG_as_voidptr(&t), SWIGTYPE_p_log_message, 0); } // @nb ownership PyObject* pythonize(const IfcGeom::ConversionResultShape* t) { return SWIG_NewPointerObj(SWIG_as_voidptr(t), SWIGTYPE_p_IfcGeom__ConversionResultShape, SWIG_POINTER_OWN); } // PyObject* pythonize(const IfcGeom::ConversionResultShape* t) { return SWIG_NewPointerObj(SWIG_as_voidptr(t), SWIGTYPE_p_IfcGeom__ConversionResultShape, 0); } diff --git a/src/ifcwrap/utils/typemaps_in.i b/src/ifcwrap/utils/typemaps_in.i index 86de15a28d..baae0ced2e 100644 --- a/src/ifcwrap/utils/typemaps_in.i +++ b/src/ifcwrap/utils/typemaps_in.i @@ -406,3 +406,21 @@ CREATE_OPTIONAL_TYPEMAP_IN(std::string, string, str) CREATE_SET_TYPEMAP_IN(int) CREATE_SET_TYPEMAP_IN(std::string) + +// for the logger codes +%typemap(typecheck, precedence=SWIG_TYPECHECK_STRING) SWIGTYPE &code_prefix { + $1 = PyUnicode_Check($input); +} +%typemap(in) SWIGTYPE &code_prefix (char tmp[4]) { + Py_ssize_t len = 0; + const char *s = PyUnicode_AsUTF8AndSize($input, &len); + + if (!s || len != 3) { + SWIG_exception_fail(SWIG_ValueError, "Expected Python str of length 3"); + } + + memcpy(tmp, s, 3); + tmp[3] = '\0'; + + $1 = &tmp; +} \ No newline at end of file diff --git a/src/ifcwrap/utils/typemaps_out.i b/src/ifcwrap/utils/typemaps_out.i index 111e74a2cb..4fbc3ff05e 100644 --- a/src/ifcwrap/utils/typemaps_out.i +++ b/src/ifcwrap/utils/typemaps_out.i @@ -108,6 +108,7 @@ CREATE_VECTOR_TYPEMAP_OUT(IfcParse::inverse_attribute const *) CREATE_VECTOR_TYPEMAP_OUT(IfcParse::entity const *) CREATE_VECTOR_TYPEMAP_OUT(IfcParse::declaration const *) CREATE_VECTOR_TYPEMAP_OUT(IfcGeom::ConversionResultShape *) +CREATE_VECTOR_TYPEMAP_OUT(log_message) %typemap(out) ifcopenshell::geometry::Settings::value_variant_t { pythonizing_visitor vis; diff --git a/src/serializers/ColladaSerializer.h b/src/serializers/ColladaSerializer.h index 690b8b7c6c..3fcd22f5ad 100644 --- a/src/serializers/ColladaSerializer.h +++ b/src/serializers/ColladaSerializer.h @@ -219,8 +219,8 @@ private: std::string unit_name; float unit_magnitude; public: - ColladaSerializer(const std::string& dae_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings) - : WriteOnlyGeometrySerializer(geometry_settings, settings) + ColladaSerializer(const std::string& dae_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger& logger = Logger::Root()) + : WriteOnlyGeometrySerializer(geometry_settings, settings, logger) , exporter("IfcOpenShell", dae_filename, this, settings.get().get() >= 15) { exporter.serializer = this; diff --git a/src/serializers/GltfSerializer.cpp b/src/serializers/GltfSerializer.cpp index bb179bb000..2d3b12c5e3 100644 --- a/src/serializers/GltfSerializer.cpp +++ b/src/serializers/GltfSerializer.cpp @@ -53,8 +53,8 @@ static const uint32_t PRIM_TRIANGLE_FAN = 6; static const uint32_t ELEMENT_ARRAY_BUFFER = 34963; static const uint32_t ARRAY_BUFFER = 34962; -GltfSerializer::GltfSerializer(const std::string& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings) - : WriteOnlyGeometrySerializer(geometry_settings, settings) +GltfSerializer::GltfSerializer(const std::string& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger& logger) + : WriteOnlyGeometrySerializer(geometry_settings, settings, logger) , filename_(filename) , tmp_filename1_(filename + ".indices.tmp") , tmp_filename2_(filename + ".vertices.tmp") @@ -519,7 +519,7 @@ namespace { } void proj_log(void *, int, const char* c) { - Logger::Error("SER", 1, "PROJ: " + std::string(c)); + logger_.Error("SER", 1, "PROJ: " + std::string(c)); } } @@ -650,7 +650,7 @@ void GltfSerializer::setFile(IfcParse::IfcFile* f) { NULL); if (!P) { - Logger::Error("SER", 2, "Failed to create PROJ transformation object"); + logger_.Error("SER", 2, "Failed to create PROJ transformation object"); return; } @@ -662,7 +662,7 @@ void GltfSerializer::setFile(IfcParse::IfcFile* f) { wgs84_point = proj_trans(P, PJ_FWD, a); - Logger::Notice("SER", 3, "Calculated latitude: " + std::to_string(wgs84_point.lp.lam) + " longitude: " + std::to_string(wgs84_point.lp.phi)); + logger_.Notice("SER", 3, "Calculated latitude: " + std::to_string(wgs84_point.lp.lam) + " longitude: " + std::to_string(wgs84_point.lp.phi)); } std::swap(wgs84_point.lp.phi, wgs84_point.lp.lam); @@ -687,7 +687,7 @@ void GltfSerializer::setFile(IfcParse::IfcFile* f) { PJ *ellipsoid_crs = proj_create(C, ellipsoid_def); if (!ellipsoid_crs) { - Logger::Error("SER", 4, "Failed to create ellipsoid CRS"); + logger_.Error("SER", 4, "Failed to create ellipsoid CRS"); return; } diff --git a/src/serializers/GltfSerializer.h b/src/serializers/GltfSerializer.h index d3754d90a0..0f9ced9031 100644 --- a/src/serializers/GltfSerializer.h +++ b/src/serializers/GltfSerializer.h @@ -43,7 +43,7 @@ private: int writeMaterial(const ifcopenshell::geometry::taxonomy::style::ptr style); public: - GltfSerializer(const std::string& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings); + GltfSerializer(const std::string& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger& logger = Logger::Root()); virtual ~GltfSerializer(); bool ready(); void writeHeader(); diff --git a/src/serializers/HdfSerializer.cpp b/src/serializers/HdfSerializer.cpp index 092413abae..15d7fa4cb7 100644 --- a/src/serializers/HdfSerializer.cpp +++ b/src/serializers/HdfSerializer.cpp @@ -55,8 +55,8 @@ herr_t print_stack(hid_t /*estack*/, void*) { return 0; } -HdfSerializer::HdfSerializer(const std::string& hdf_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, bool read_only) - : GeometrySerializer(geometry_settings, settings) +HdfSerializer::HdfSerializer(const std::string& hdf_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, bool read_only, Logger& logger) + : GeometrySerializer(geometry_settings, settings, logger) , hdf_filename(hdf_filename) , settings_(settings) { @@ -726,4 +726,4 @@ const H5std_string HdfSerializer::DATASET_NAME_PLACEMENT = "placement"; const H5std_string HdfSerializer::GROUP_NAME_MESH = "mesh"; -#endif \ No newline at end of file +#endif diff --git a/src/serializers/HdfSerializer.h b/src/serializers/HdfSerializer.h index 6dab05eaad..5380650e60 100644 --- a/src/serializers/HdfSerializer.h +++ b/src/serializers/HdfSerializer.h @@ -96,7 +96,7 @@ private: void write_style(surface_style_serialization& data, const ifcopenshell::geometry::taxonomy::style::ptr& s); public: - HdfSerializer(const std::string& hdf_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, bool read_only=false); + HdfSerializer(const std::string& hdf_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, bool read_only=false, Logger& logger = Logger::Root()); virtual ~HdfSerializer() {} bool ready(); void writeHeader(); diff --git a/src/serializers/IgesSerializer.h b/src/serializers/IgesSerializer.h index 0dbb257ceb..a1e4fc293c 100644 --- a/src/serializers/IgesSerializer.h +++ b/src/serializers/IgesSerializer.h @@ -40,8 +40,8 @@ private: public: /// @note IGESControl_Controller::Init() must be called prior to instantiating IgesSerializer. /// See http://tracker.dev.opencascade.org/view.php?id=23679 for more information. - IgesSerializer(const std::string& out_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings) - : OpenCascadeBasedSerializer(out_filename, geometry_settings, settings) + IgesSerializer(const std::string& out_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger& logger = Logger::Root()) + : OpenCascadeBasedSerializer(out_filename, geometry_settings, settings, logger) {} virtual ~IgesSerializer() {} void writeShape(const std::string&, const TopoDS_Shape& shape) { @@ -54,7 +54,7 @@ public: const char* symbol = getSymbolForUnitMagnitude(magnitude); if (symbol) { #ifdef HAVE_CONFIG_H - Logger::Warning("SER", 5, "Setting IGES units not supported on OCE"); + logger_.Warning("SER", 5, "Setting IGES units not supported on OCE"); #else Interface_Static::SetCVal("xstep.cascade.unit", symbol); Interface_Static::SetCVal("write.iges.unit", symbol); diff --git a/src/serializers/JsonSerializer.cpp b/src/serializers/JsonSerializer.cpp index d14e4aff0e..b025456d9c 100644 --- a/src/serializers/JsonSerializer.cpp +++ b/src/serializers/JsonSerializer.cpp @@ -42,18 +42,19 @@ void JsonSerializerFactory::Factory::bind(const std::string& schema_name, fn f) this->insert(std::make_pair(schema_name_lower, f)); } -JsonSerializer* JsonSerializerFactory::Factory::construct(const std::string& schema_name, IfcParse::IfcFile* file, std::string json_filename, JsonSerializer::Dialect dialect) { +JsonSerializer* JsonSerializerFactory::Factory::construct(const std::string& schema_name, IfcParse::IfcFile* file, std::string json_filename, JsonSerializer::Dialect dialect, Logger& logger) { const std::string schema_name_lower = boost::to_lower_copy(schema_name); auto it = this->find(schema_name_lower); if (it == this->end()) { throw IfcParse::IfcException("No Json serializer registered for " + schema_name); } - return it->second(file, json_filename, dialect); + return it->second(file, json_filename, dialect, logger); } -JsonSerializer::JsonSerializer(IfcParse::IfcFile* file, const std::string& json_filename, JsonSerializer::Dialect dialect) { +JsonSerializer::JsonSerializer(IfcParse::IfcFile* file, const std::string& json_filename, JsonSerializer::Dialect dialect, Logger& logger) + : Serializer(logger) { if (file) { - implementation_ = JsonSerializerFactory::implementations().construct(file->schema()->name(), file, json_filename, dialect); + implementation_ = JsonSerializerFactory::implementations().construct(file->schema()->name(), file, json_filename, dialect, logger_); } } diff --git a/src/serializers/JsonSerializer.h b/src/serializers/JsonSerializer.h index 3aa4e0a002..ba7283a22c 100644 --- a/src/serializers/JsonSerializer.h +++ b/src/serializers/JsonSerializer.h @@ -23,7 +23,7 @@ class SERIALIZERS_API JsonSerializer : public Serializer { Dialect dialect_; public: - JsonSerializer(IfcParse::IfcFile* file, const std::string& json_filename, Dialect dialect = Dialect::JSON_DIALECT_CREOOX); + JsonSerializer(IfcParse::IfcFile* file, const std::string& json_filename, Dialect dialect = Dialect::JSON_DIALECT_CREOOX, Logger& logger = Logger::Root()); virtual ~JsonSerializer() {} @@ -35,13 +35,13 @@ class SERIALIZERS_API JsonSerializer : public Serializer { }; struct SERIALIZERS_API JsonSerializerFactory { - typedef boost::function3 fn; + typedef boost::function4 fn; class Factory : public std::map { public: Factory(); void bind(const std::string& schema_name, fn); - JsonSerializer* construct(const std::string& schema_name, IfcParse::IfcFile*, std::string, JsonSerializer::Dialect); + JsonSerializer* construct(const std::string& schema_name, IfcParse::IfcFile*, std::string, JsonSerializer::Dialect, Logger& logger = Logger::Root()); }; static Factory& implementations(); diff --git a/src/serializers/OpenCascadeBasedSerializer.h b/src/serializers/OpenCascadeBasedSerializer.h index 44b252b27c..d7419b3237 100644 --- a/src/serializers/OpenCascadeBasedSerializer.h +++ b/src/serializers/OpenCascadeBasedSerializer.h @@ -36,8 +36,8 @@ protected: const std::string out_filename; const char* getSymbolForUnitMagnitude(float mag); public: - explicit OpenCascadeBasedSerializer(const std::string& out_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings) - : WriteOnlyGeometrySerializer(geometry_settings, settings) + explicit OpenCascadeBasedSerializer(const std::string& out_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger& logger = Logger::Root()) + : WriteOnlyGeometrySerializer(geometry_settings, settings, logger) , out_filename(out_filename) {} virtual ~OpenCascadeBasedSerializer() {} diff --git a/src/serializers/RocksDbSerializer.cpp b/src/serializers/RocksDbSerializer.cpp index 2a6221b670..112445d3f6 100644 --- a/src/serializers/RocksDbSerializer.cpp +++ b/src/serializers/RocksDbSerializer.cpp @@ -9,8 +9,9 @@ #include "../ifcparse/IfcLogger.h" -RocksDbSerializer::RocksDbSerializer(IfcParse::IfcFile* file, const std::string& rocksdb_filename) - : file_(file) +RocksDbSerializer::RocksDbSerializer(IfcParse::IfcFile* file, const std::string& rocksdb_filename, Logger& logger) + : Serializer(logger) + , file_(file) , rocksdb_filename_(rocksdb_filename) { /*rocksdb::Options options; @@ -26,8 +27,9 @@ RocksDbSerializer::RocksDbSerializer(IfcParse::IfcFile* file, const std::string& output_file_->calculate_unit_factors = false; } -RocksDbSerializer::RocksDbSerializer(const std::string& input_filename, const std::string& rocksdb_filename, bool stream) - : file_(input_filename) +RocksDbSerializer::RocksDbSerializer(const std::string& input_filename, const std::string& rocksdb_filename, bool stream, Logger& logger) + : Serializer(logger) + , file_(input_filename) , rocksdb_filename_(rocksdb_filename) { } @@ -378,4 +380,4 @@ void RocksDbSerializer::finalize() { } -#endif \ No newline at end of file +#endif diff --git a/src/serializers/RocksDbSerializer.h b/src/serializers/RocksDbSerializer.h index 2ed7a0771d..495201e4ab 100644 --- a/src/serializers/RocksDbSerializer.h +++ b/src/serializers/RocksDbSerializer.h @@ -18,8 +18,8 @@ private: void write_streaming_(); void write_non_streaming_(); public: - RocksDbSerializer(IfcParse::IfcFile* file, const std::string& rocksdb_filename); - RocksDbSerializer(const std::string& input_filename, const std::string& rocksdb_filename, bool stream); + RocksDbSerializer(IfcParse::IfcFile* file, const std::string& rocksdb_filename, Logger& logger = Logger::Root()); + RocksDbSerializer(const std::string& input_filename, const std::string& rocksdb_filename, bool stream, Logger& logger = Logger::Root()); virtual ~RocksDbSerializer() {} @@ -31,4 +31,4 @@ public: }; #endif -#endif \ No newline at end of file +#endif diff --git a/src/serializers/StepSerializer.h b/src/serializers/StepSerializer.h index da3335bde4..85dabf4084 100644 --- a/src/serializers/StepSerializer.h +++ b/src/serializers/StepSerializer.h @@ -34,8 +34,8 @@ class StepSerializer : public OpenCascadeBasedSerializer private: STEPControl_Writer writer; public: - explicit StepSerializer(const std::string& out_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& serializer_settings) - : OpenCascadeBasedSerializer(out_filename, geometry_settings, serializer_settings) + explicit StepSerializer(const std::string& out_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& serializer_settings, Logger& logger = Logger::Root()) + : OpenCascadeBasedSerializer(out_filename, geometry_settings, serializer_settings, logger) {} virtual ~StepSerializer() {} void writeShape(const std::string& name, const TopoDS_Shape& shape) { diff --git a/src/serializers/SvgSerializer.cpp b/src/serializers/SvgSerializer.cpp index dd95972117..b870a3f825 100644 --- a/src/serializers/SvgSerializer.cpp +++ b/src/serializers/SvgSerializer.cpp @@ -139,13 +139,13 @@ void SvgSerializer::write(path_object& p, const TopoDS_Shape& comp_or_wire, boos BRep_Tool::CurveOnSurface(edge, curve2d, surf, loc, u1, u2); if (curve2d.IsNull()) { - Logger::Error("SER", 20, "Failed to obtain 2d and 3d curve from edge"); + logger_.Error("SER", 20, "Failed to obtain 2d and 3d curve from edge"); continue; } Handle(Standard_Type) sty = surf->DynamicType(); if (sty != STANDARD_TYPE(Geom_Plane)) { - Logger::Error("SER", 21, "Non-planar p-curves are not supported by this serializer"); + logger_.Error("SER", 21, "Non-planar p-curves are not supported by this serializer"); continue; } @@ -222,7 +222,7 @@ void SvgSerializer::write(path_object& p, const TopoDS_Shape& comp_or_wire, boos std::stringstream ss; ss << "Skipping full circle/ellipse inside aggregated (id " << p.first << ")"; - Logger::Warning("SER", 22, ss.str()); + logger_.Warning("SER", 22, ss.str()); } } @@ -650,7 +650,7 @@ void SvgSerializer::write(const IfcGeom::BRepElement* brep_obj) { BRepBndLib::AddOBB(compound_unmirrored, *view_box_3d_, false, false, false); #endif } else { - Logger::Error("SER", 23, "Failed to box or edge from drawing annotation"); + logger_.Error("SER", 23, "Failed to box or edge from drawing annotation"); } std::vector props; @@ -797,7 +797,7 @@ void SvgSerializer::write(const geometry_data& data) { if (data.storey) { section_heights_storage.push_back(horizontal_plan{ data.storey, data.storey_elevation, +1. }); } else { - Logger::Warning("SER", 24, "No global section height and unable to determine building storey for:", data.product); + logger_.Warning("SER", 24, "No global section height and unable to determine building storey for:", data.product); return; } } @@ -812,7 +812,7 @@ void SvgSerializer::write(const geometry_data& data) { Bnd_OBB obb; BRepBndLib::AddOBB(compound_unmirrored, obb, false, false, false); if (view_box_3d_->IsOut(obb)) { - Logger::Notice("SER", 25, "Not including element due to viewBox", data.product); + logger_.Notice("SER", 25, "Not including element due to viewBox", data.product); return; } } @@ -859,7 +859,7 @@ void SvgSerializer::write(const geometry_data& data) { } } } catch (std::exception& e) { - Logger::Error("SER", 26, e); + logger_.Error("SER", 26, e); } if (operation_type && ((*operation_type == "SINGLE_SWING_LEFT") || (*operation_type == "SINGLE_SWING_RIGHT"))) { @@ -1112,7 +1112,7 @@ void SvgSerializer::write(const geometry_data& data) { compound_to_hlr = &subtracted_shape; } catch (...) { - Logger::Error("SER", 27, "Failed to cut element for HLR", data.product); + logger_.Error("SER", 27, "Failed to cut element for HLR", data.product); } } } @@ -1204,11 +1204,11 @@ void SvgSerializer::write(const geometry_data& data) { if (storey) { auto it = storey_hlr.find(storey); if (it == storey_hlr.end()) { - it = storey_hlr.insert({ storey, hlr_t(use_prefiltering_, use_hlr_poly_, segment_projection_, projection_plane) }).first; + it = storey_hlr.insert({ storey, hlr_t(logger_, use_prefiltering_, use_hlr_poly_, segment_projection_, projection_plane) }).first; } it->second.add(*compound_to_hlr, data.product); } else { - Logger::Warning("SER", 28, "Unable to invoke HLR due to absence of storey containment", data.product); + logger_.Warning("SER", 28, "Unable to invoke HLR due to absence of storey containment", data.product); } } else if (hlr) { hlr->add(*compound_to_hlr, data.product); @@ -1681,7 +1681,7 @@ void SvgSerializer::write(const geometry_data& data) { } if (!emitted) { - Logger::Warning("SER", 29, "Element not written to SVG due to section heights", data.product); + logger_.Warning("SER", 29, "Element not written to SVG due to section heights", data.product); } } @@ -1862,7 +1862,7 @@ void SvgSerializer::addTextAnnotations(const drawing_key& k) { auto desc = (std::string) ds; if (object_type == "Text") { - auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(file, geometry_settings_); + auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(file, geometry_settings_, logger_); auto item = mapping->map(pl); auto matrix = ifcopenshell::geometry::taxonomy::cast(item); delete mapping; @@ -2066,7 +2066,7 @@ void SvgSerializer::finalize() { // @todo do we have always have pln here? if (use_hlr && pln) { - hlr = new hlr_t(use_prefiltering_, use_hlr_poly_, segment_projection_, *pln); + hlr = new hlr_t(logger_, use_prefiltering_, use_hlr_poly_, segment_projection_, *pln); } section_data_ = std::vector{ sd }; @@ -2317,7 +2317,7 @@ void SvgSerializer::setFile(IfcParse::IfcFile* f) { auto storeys = f->instances_by_type("IfcBuildingStorey"); if (!storeys || storeys->size() == 0) { - auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(file, geometry_settings_); + auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(file, geometry_settings_, logger_); std::vector to_derive_from; to_derive_from.push_back(f->schema()->declaration_by_name("IfcBuilding")); @@ -2337,7 +2337,7 @@ void SvgSerializer::setFile(IfcParse::IfcFile* f) { #ifdef TAXONOMY_USE_NAKED_PTR delete matrix; #endif - Logger::Warning("SER", 30, "No building storeys encountered, used for reference:", product); + logger_.Warning("SER", 30, "No building storeys encountered, used for reference:", product); return; } } @@ -2347,7 +2347,7 @@ void SvgSerializer::setFile(IfcParse::IfcFile* f) { delete mapping; - Logger::Warning("SER", 31, "No building storeys encountered, output might be invalid or missing"); + logger_.Warning("SER", 31, "No building storeys encountered, output might be invalid or missing"); } } @@ -2358,7 +2358,7 @@ void SvgSerializer::setSectionHeight(double h, const IfcUtil::IfcBaseEntity* sto void SvgSerializer::setSectionHeightsFromStoreys(double offset) { if (!file) { - Logger::Error("SER", 32, "No file specified"); + logger_.Error("SER", 32, "No file specified"); return; } with_section_heights_from_storey_ = true; @@ -2373,7 +2373,7 @@ void SvgSerializer::setSectionHeightsFromStoreys(double offset) { try { elev = attr_value; } catch (std::exception& e) { - Logger::Error("SER", 33, e); + logger_.Error("SER", 33, e); continue; } if (!section_data_->empty()) { diff --git a/src/serializers/SvgSerializer.h b/src/serializers/SvgSerializer.h index 3d76238157..4bbcd98b1e 100644 --- a/src/serializers/SvgSerializer.h +++ b/src/serializers/SvgSerializer.h @@ -368,10 +368,13 @@ namespace { std::multimap large_ortho_faces_; std::list> items_; + Logger& logger_; + public: - prefiltered_hlr(bool use_prefiltering, bool use_hlr_poly, bool segment_projection, const gp_Pln& view_direction) - : use_prefiltering_(use_prefiltering) + prefiltered_hlr(Logger& logger, bool use_prefiltering, bool use_hlr_poly, bool segment_projection, const gp_Pln& view_direction) + : logger_(logger) + , use_prefiltering_(use_prefiltering) , use_hlr_poly_(use_hlr_poly) , segment_projection_(segment_projection) // @nb negative z in accordance with occt projector convention (and opengl) @@ -468,7 +471,7 @@ namespace { } } - Logger::Notice("SER", 34, "Included " + std::to_string(n_faces_included) + " faces out of " + std::to_string(n_total) + " after prefiltering"); + logger_.Notice("SER", 34, "Included " + std::to_string(n_faces_included) + " faces out of " + std::to_string(n_total) + " after prefiltering"); auto it = items_.insert(items_.end(), { product, C }); @@ -517,7 +520,7 @@ namespace { } } if (use_prefiltering_) { - Logger::Notice("SER", 35, "Included " + std::to_string(n_included) + " elements out of " + std::to_string(items_.size()) + " after prefiltering"); + logger_.Notice("SER", 35, "Included " + std::to_string(n_included) + " elements out of " + std::to_string(items_.size()) + " after prefiltering"); } hlr_calc vis(projector_); @@ -593,8 +596,8 @@ protected: subtract_before_project subtraction_settings_; public: - SvgSerializer(const stream_or_filename& out_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings) - : WriteOnlyGeometrySerializer(geometry_settings, settings) + SvgSerializer(const stream_or_filename& out_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger& logger = Logger::Root()) + : WriteOnlyGeometrySerializer(geometry_settings, settings, logger) , svg_file(out_filename) , xmin(+std::numeric_limits::infinity()) , ymin(+std::numeric_limits::infinity()) diff --git a/src/serializers/TtlWktSerializer.cpp b/src/serializers/TtlWktSerializer.cpp index 2fd4a3c18f..ab6343fac4 100644 --- a/src/serializers/TtlWktSerializer.cpp +++ b/src/serializers/TtlWktSerializer.cpp @@ -225,8 +225,8 @@ namespace { } } -TtlWktSerializer::TtlWktSerializer(const stream_or_filename& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings) - : WriteOnlyGeometrySerializer(geometry_settings, settings) +TtlWktSerializer::TtlWktSerializer(const stream_or_filename& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger& logger) + : WriteOnlyGeometrySerializer(geometry_settings, settings, logger) , filename_(filename) { const auto& tri_setting = geometry_settings.get().get(); @@ -473,11 +473,11 @@ void TtlWktSerializer::write(const IfcGeom::BRepElement* brep_obj) { if ((polygons_by_area.rbegin()->first > (0.6 * rectangle_area)) || (height < (1. + 1.e-5))) { // Found sufficiently large polygon if (emitted_warning) { - Logger::Warning("SER", 36, "Found larger polygon area (" + std::to_string(polygons_by_area.rbegin()->first) + ")."); + logger_.Warning("SER", 36, "Found larger polygon area (" + std::to_string(polygons_by_area.rbegin()->first) + ")."); } break; } else if (!emitted_warning) { - Logger::Warning("SER", 37, "Section polygon area is small compared to bounding box area (" + std::to_string(polygons_by_area.rbegin()->first) + " < " + std::to_string(0.6 * rectangle_area) + "). Trying again with different section height."); + logger_.Warning("SER", 37, "Section polygon area is small compared to bounding box area (" + std::to_string(polygons_by_area.rbegin()->first) + " < " + std::to_string(0.6 * rectangle_area) + "). Trying again with different section height."); emitted_warning = true; } } diff --git a/src/serializers/TtlWktSerializer.h b/src/serializers/TtlWktSerializer.h index 3b601e4a44..d332ffaa89 100644 --- a/src/serializers/TtlWktSerializer.h +++ b/src/serializers/TtlWktSerializer.h @@ -32,7 +32,7 @@ class SERIALIZERS_API TtlWktSerializer : public WriteOnlyGeometrySerializer { private: stream_or_filename filename_; public: - TtlWktSerializer(const stream_or_filename& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings); + TtlWktSerializer(const stream_or_filename& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger& logger = Logger::Root()); virtual ~TtlWktSerializer() {} bool ready(); void writeHeader(); diff --git a/src/serializers/USDSerializer.cpp b/src/serializers/USDSerializer.cpp index 4a4b0a7cf6..5139ad3945 100644 --- a/src/serializers/USDSerializer.cpp +++ b/src/serializers/USDSerializer.cpp @@ -36,8 +36,8 @@ #include -USDSerializer::USDSerializer(const std::string& out_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings): - WriteOnlyGeometrySerializer(geometry_settings, settings), +USDSerializer::USDSerializer(const std::string& out_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger& logger): + WriteOnlyGeometrySerializer(geometry_settings, settings, logger), filename_(out_filename) { std::size_t found = filename_.find_last_of("/\\"); diff --git a/src/serializers/USDSerializer.h b/src/serializers/USDSerializer.h index f9b50bc22c..5453bb9a3e 100644 --- a/src/serializers/USDSerializer.h +++ b/src/serializers/USDSerializer.h @@ -86,7 +86,7 @@ private: std::set emitted_names_; std::map element_names_; public: - USDSerializer(const std::string&, const ifcopenshell::geometry::Settings&, const ifcopenshell::geometry::SerializerSettings&); + USDSerializer(const std::string&, const ifcopenshell::geometry::Settings&, const ifcopenshell::geometry::SerializerSettings&, Logger& logger = Logger::Root()); virtual ~USDSerializer(); bool ready() { return ready_; } void writeHeader(); @@ -101,4 +101,4 @@ public: #endif -#endif \ No newline at end of file +#endif diff --git a/src/serializers/WavefrontObjSerializer.cpp b/src/serializers/WavefrontObjSerializer.cpp index 848dd9beb7..536f9aeeaa 100644 --- a/src/serializers/WavefrontObjSerializer.cpp +++ b/src/serializers/WavefrontObjSerializer.cpp @@ -27,8 +27,8 @@ #include #include -WaveFrontOBJSerializer::WaveFrontOBJSerializer(const stream_or_filename& obj_filename, const stream_or_filename& mtl_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings) - : WriteOnlyGeometrySerializer(geometry_settings, settings) +WaveFrontOBJSerializer::WaveFrontOBJSerializer(const stream_or_filename& obj_filename, const stream_or_filename& mtl_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger& logger) + : WriteOnlyGeometrySerializer(geometry_settings, settings, logger) , obj_stream(obj_filename) , mtl_stream(mtl_filename) , vcount_total(1) diff --git a/src/serializers/WavefrontObjSerializer.h b/src/serializers/WavefrontObjSerializer.h index d3ea41f69e..e1436d2de3 100644 --- a/src/serializers/WavefrontObjSerializer.h +++ b/src/serializers/WavefrontObjSerializer.h @@ -35,7 +35,7 @@ private: size_t vcount_total, ncount_total; std::set materials; public: - WaveFrontOBJSerializer(const stream_or_filename& obj_filename, const stream_or_filename& mtl_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings); + WaveFrontOBJSerializer(const stream_or_filename& obj_filename, const stream_or_filename& mtl_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger& logger = Logger::Root()); virtual ~WaveFrontOBJSerializer() {} bool ready(); void writeHeader(); diff --git a/src/serializers/XmlSerializer.cpp b/src/serializers/XmlSerializer.cpp index 6607479448..24f0cf435b 100644 --- a/src/serializers/XmlSerializer.cpp +++ b/src/serializers/XmlSerializer.cpp @@ -21,19 +21,20 @@ void XmlSerializerFactory::Factory::bind(const std::string& schema_name, fn f) { this->insert(std::make_pair(schema_name_lower, f)); } -XmlSerializer* XmlSerializerFactory::Factory::construct(const std::string& schema_name, IfcParse::IfcFile* file, std::string xml_filename) { +XmlSerializer* XmlSerializerFactory::Factory::construct(const std::string& schema_name, IfcParse::IfcFile* file, std::string xml_filename, Logger& logger) { const std::string schema_name_lower = boost::to_lower_copy(schema_name); typename std::map::const_iterator it; it = this->find(schema_name_lower); if (it == this->end()) { throw IfcParse::IfcException("No XML serializer registered for " + schema_name); } - return it->second(file, xml_filename); + return it->second(file, xml_filename, logger); } -XmlSerializer::XmlSerializer(IfcParse::IfcFile* file, const std::string& xml_filename) { +XmlSerializer::XmlSerializer(IfcParse::IfcFile* file, const std::string& xml_filename, Logger& logger) + : Serializer(logger) { if (file) { - implementation_ = XmlSerializerFactory::implementations().construct(file->schema()->name(), file, xml_filename); + implementation_ = XmlSerializerFactory::implementations().construct(file->schema()->name(), file, xml_filename, logger_); } } diff --git a/src/serializers/XmlSerializer.h b/src/serializers/XmlSerializer.h index 4a269f8c5a..908f165734 100644 --- a/src/serializers/XmlSerializer.h +++ b/src/serializers/XmlSerializer.h @@ -16,7 +16,7 @@ protected: std::string xml_filename; public: - XmlSerializer(IfcParse::IfcFile* file, const std::string& xml_filename); + XmlSerializer(IfcParse::IfcFile* file, const std::string& xml_filename, Logger& logger = Logger::Root()); virtual ~XmlSerializer() {} @@ -28,13 +28,13 @@ public: }; struct SERIALIZERS_API XmlSerializerFactory { - typedef boost::function2 fn; + typedef boost::function3 fn; class Factory : public std::map { public: Factory(); void bind(const std::string& schema_name, fn); - XmlSerializer* construct(const std::string& schema_name, IfcParse::IfcFile*, std::string); + XmlSerializer* construct(const std::string& schema_name, IfcParse::IfcFile*, std::string, Logger& logger = Logger::Root()); }; static Factory& implementations(); diff --git a/src/serializers/schema_dependent/JsonSerializer.cpp b/src/serializers/schema_dependent/JsonSerializer.cpp index 05d188aeb7..e44e88b26d 100644 --- a/src/serializers/schema_dependent/JsonSerializer.cpp +++ b/src/serializers/schema_dependent/JsonSerializer.cpp @@ -34,8 +34,8 @@ using json = nlohmann::json; namespace { struct POSTFIX_SCHEMA(factory_t) { - JsonSerializer* operator()(IfcParse::IfcFile* file, const std::string& json_filename, JsonSerializer::Dialect dialect) const { - POSTFIX_SCHEMA(JsonSerializer)* s = new POSTFIX_SCHEMA(JsonSerializer)(file, json_filename, dialect); + JsonSerializer* operator()(IfcParse::IfcFile* file, const std::string& json_filename, JsonSerializer::Dialect dialect, Logger& logger) const { + POSTFIX_SCHEMA(JsonSerializer)* s = new POSTFIX_SCHEMA(JsonSerializer)(file, json_filename, dialect, logger); s->setFile(file); return s; } @@ -81,7 +81,7 @@ class get_type_visitor : public boost::static_visitor { // Returns related entity instances using IFC's objectified relationship // model. The second and third argument require a member function pointer. template -auto get_related(T* t, F f, G g) { +auto get_related(Logger& logger, T* t, F f, G g) { typename U::list::ptr li = (*t.*f)()->template as(); typename aggregate_of::ptr acc(new aggregate_of); for (typename U::list::it it = li->begin(); it != li->end(); ++it) { @@ -89,13 +89,13 @@ auto get_related(T* t, F f, G g) { try { acc->push((*u.*g)()->template as()); } catch (IfcParse::IfcException& e) { - Logger::Error("SER", 6, e); + logger.Error("SER", 6, e); } } return acc; } -void format_entity_instance(IfcUtil::IfcBaseEntity* instance, json& tree, IfcUtil::IfcBaseEntity* parent = nullptr) { +void format_entity_instance(IfcUtil::IfcBaseEntity* instance, json& tree, Logger& logger, IfcUtil::IfcBaseEntity* parent = nullptr) { /* { "id" : string, // Element GUID (IFC GloballyUniqueId) @@ -149,7 +149,7 @@ void format_entity_instance(IfcUtil::IfcBaseEntity* instance, json& tree, IfcUti } if (auto* obj = instance->as()) { - IfcSchema::IfcPropertySetDefinition::list::ptr property_sets = get_related(obj, &IfcSchema::IfcObject::IsDefinedBy, &IfcSchema::IfcRelDefinesByProperties::RelatingPropertyDefinition); + IfcSchema::IfcPropertySetDefinition::list::ptr property_sets = get_related(logger, obj, &IfcSchema::IfcObject::IsDefinedBy, &IfcSchema::IfcRelDefinesByProperties::RelatingPropertyDefinition); if (!property_sets && property_sets->size()) { child["propertySetIds"] = json::array(); for (IfcSchema::IfcPropertySetDefinition::list::it it = property_sets->begin(); it != property_sets->end(); ++it) { @@ -166,11 +166,11 @@ void format_entity_instance(IfcUtil::IfcBaseEntity* instance, json& tree, IfcUti // A function to be called recursively. Template specialization is used // to descend into decomposition, containment and property relationships. template -void descend(A* instance, json& tree, IfcUtil::IfcBaseEntity* parent = nullptr) { +void descend(A* instance, json& tree, Logger& logger, IfcUtil::IfcBaseEntity* parent = nullptr) { if (instance->declaration().is(IfcSchema::IfcObjectDefinition::Class())) { - descend(instance->template as(), tree, parent); + descend(instance->template as(), tree, logger, parent); } else { - format_entity_instance(instance, tree); + format_entity_instance(instance, tree, logger); } } @@ -179,7 +179,7 @@ void descend(A* instance, json& tree, IfcUtil::IfcBaseEntity* parent = nullptr) // Descends into the tree by recursing into IfcRelContainedInSpatialStructure, // IfcRelDecomposes, IfcRelDefinesByType, IfcRelDefinesByProperties relations. template <> -void descend(IfcSchema::IfcObjectDefinition* product, json& tree, IfcUtil::IfcBaseEntity* parent) { +void descend(IfcSchema::IfcObjectDefinition* product, json& tree, Logger& logger, IfcUtil::IfcBaseEntity* parent) { if (product->declaration().is(IfcSchema::IfcElement::Class())) { auto voids = product->as()->FillsVoids(); if (voids && voids->size() == 1 && (*voids->begin())->RelatingOpeningElement() != parent) { @@ -188,49 +188,49 @@ void descend(IfcSchema::IfcObjectDefinition* product, json& tree, IfcUtil::IfcBa } } - format_entity_instance(product, tree, parent); + format_entity_instance(product, tree, logger, parent); if (product->declaration().is(IfcSchema::IfcOpeningElement::Class())) { IfcSchema::IfcOpeningElement* opening = product->as(); IfcSchema::IfcElement::list::ptr fills = get_related( - opening, &IfcSchema::IfcOpeningElement::HasFillings, &IfcSchema::IfcRelFillsElement::RelatedBuildingElement); + logger, opening, &IfcSchema::IfcOpeningElement::HasFillings, &IfcSchema::IfcRelFillsElement::RelatedBuildingElement); for (IfcSchema::IfcElement::list::it it = fills->begin(); it != fills->end(); ++it) { - descend(*it, tree, product); + descend(*it, tree, logger, product); } } if (product->declaration().is(IfcSchema::IfcSpatialStructureElement::Class())) { IfcSchema::IfcSpatialStructureElement* structure = product->as(); - IfcSchema::IfcObjectDefinition::list::ptr elements = get_related(structure, &IfcSchema::IfcSpatialStructureElement::ContainsElements, &IfcSchema::IfcRelContainedInSpatialStructure::RelatedElements); + IfcSchema::IfcObjectDefinition::list::ptr elements = get_related(logger, structure, &IfcSchema::IfcSpatialStructureElement::ContainsElements, &IfcSchema::IfcRelContainedInSpatialStructure::RelatedElements); for (IfcSchema::IfcObjectDefinition::list::it it = elements->begin(); it != elements->end(); ++it) { - descend(*it, tree, product); + descend(*it, tree, logger, product); } } if (product->declaration().is(IfcSchema::IfcElement::Class())) { IfcSchema::IfcElement* element = static_cast(product); IfcSchema::IfcOpeningElement::list::ptr openings = get_related( - element, &IfcSchema::IfcElement::HasOpenings, &IfcSchema::IfcRelVoidsElement::RelatedOpeningElement); + logger, element, &IfcSchema::IfcElement::HasOpenings, &IfcSchema::IfcRelVoidsElement::RelatedOpeningElement); for (IfcSchema::IfcOpeningElement::list::it it = openings->begin(); it != openings->end(); ++it) { - descend(*it, tree, product); + descend(*it, tree, logger, product); } } #ifdef SCHEMA_IfcRelDecomposes_HAS_RelatedObjects - IfcSchema::IfcObjectDefinition::list::ptr structures = get_related(product, &IfcSchema::IfcObjectDefinition::IsDecomposedBy, &IfcSchema::IfcRelDecomposes::RelatedObjects); + IfcSchema::IfcObjectDefinition::list::ptr structures = get_related(logger, product, &IfcSchema::IfcObjectDefinition::IsDecomposedBy, &IfcSchema::IfcRelDecomposes::RelatedObjects); #else - IfcSchema::IfcObjectDefinition::list::ptr structures = get_related(product, &IfcSchema::IfcObjectDefinition::IsDecomposedBy, &IfcSchema::IfcRelAggregates::RelatedObjects); + IfcSchema::IfcObjectDefinition::list::ptr structures = get_related(logger, product, &IfcSchema::IfcObjectDefinition::IsDecomposedBy, &IfcSchema::IfcRelAggregates::RelatedObjects); - structures->push(get_related(product, &IfcSchema::IfcObjectDefinition::IsNestedBy, &IfcSchema::IfcRelNests::RelatedObjects)); + structures->push(get_related(logger, product, &IfcSchema::IfcObjectDefinition::IsNestedBy, &IfcSchema::IfcRelNests::RelatedObjects)); #endif for (IfcSchema::IfcObjectDefinition::list::it it = structures->begin(); it != structures->end(); ++it) { IfcSchema::IfcObjectDefinition* ob = *it; - descend(ob, tree, product); + descend(ob, tree, logger, product); } // psets are handled as part of format_entity_instance() @@ -264,7 +264,7 @@ void POSTFIX_SCHEMA(JsonSerializer)::finalize() { IfcSchema::IfcProject::list::ptr projects = file->instances_by_type(); if (projects->size() != 1) { - Logger::Message(Logger::LOG_ERROR, "SER", 7, "Expected a single IfcProject"); + logger_.Message(Logger::LOG_ERROR, "SER", 7, "Expected a single IfcProject"); return; } IfcSchema::IfcProject* project = *projects->begin(); @@ -273,7 +273,7 @@ void POSTFIX_SCHEMA(JsonSerializer)::finalize() { try { return fn(); } catch (const std::exception& e) { - Logger::Error("SER", 8, e); + logger_.Error("SER", 8, e); static std::invoke_result_t v; return v; } @@ -563,7 +563,7 @@ void POSTFIX_SCHEMA(JsonSerializer)::finalize() { } */ - descend(project, output["metaObjects"]); + descend(project, output["metaObjects"], logger_); std::ofstream f(IfcUtil::path::from_utf8(json_filename).c_str()); f << output.dump(4); @@ -859,4 +859,4 @@ void POSTFIX_SCHEMA(JsonSerializer)::finalize() { boost::property_tree::write_xml(f, root, settings); */ -#endif \ No newline at end of file +#endif diff --git a/src/serializers/schema_dependent/JsonSerializer.h b/src/serializers/schema_dependent/JsonSerializer.h index 0fd7c57040..7f9fcd8457 100644 --- a/src/serializers/schema_dependent/JsonSerializer.h +++ b/src/serializers/schema_dependent/JsonSerializer.h @@ -41,8 +41,8 @@ class POSTFIX_SCHEMA(JsonSerializer) : public JsonSerializer { ifcopenshell::geometry::abstract_mapping* mapping_; public: - POSTFIX_SCHEMA(JsonSerializer)(IfcParse::IfcFile* file, const std::string& json_filename, JsonSerializer::Dialect dialect) - : JsonSerializer(0, "", dialect), mapping_(ifcopenshell::geometry::impl::mapping_implementations().construct(file, settings_)) + POSTFIX_SCHEMA(JsonSerializer)(IfcParse::IfcFile* file, const std::string& json_filename, JsonSerializer::Dialect dialect, Logger& logger = Logger::Root()) + : JsonSerializer(0, "", dialect, logger), mapping_(ifcopenshell::geometry::impl::mapping_implementations().construct(file, settings_, logger)) { this->file = file; this->json_filename = json_filename; diff --git a/src/serializers/schema_dependent/XmlSerializer.cpp b/src/serializers/schema_dependent/XmlSerializer.cpp index 6244e15a6b..e97e8bfb74 100644 --- a/src/serializers/schema_dependent/XmlSerializer.cpp +++ b/src/serializers/schema_dependent/XmlSerializer.cpp @@ -36,8 +36,8 @@ using boost::property_tree::ptree; namespace { struct POSTFIX_SCHEMA(factory_t) { - XmlSerializer* operator()(IfcParse::IfcFile* file, const std::string& xml_filename) const { - POSTFIX_SCHEMA(XmlSerializer)* s = new POSTFIX_SCHEMA(XmlSerializer)(file, xml_filename); + XmlSerializer* operator()(IfcParse::IfcFile* file, const std::string& xml_filename, Logger& logger) const { + POSTFIX_SCHEMA(XmlSerializer)* s = new POSTFIX_SCHEMA(XmlSerializer)(file, xml_filename, logger); s->setFile(file); return s; } @@ -151,13 +151,13 @@ boost::optional format_attribute(ifcopenshell::geometry::abstract_m } // Appends to a node with possibly existing attributes -ptree* format_entity_instance(ifcopenshell::geometry::abstract_mapping* mapping, IfcUtil::IfcBaseEntity* instance, ptree& child, ptree& tree, bool as_link = false) { +ptree* format_entity_instance(Logger& logger, ifcopenshell::geometry::abstract_mapping* mapping, IfcUtil::IfcBaseEntity* instance, ptree& child, ptree& tree, bool as_link = false) { const unsigned n = instance->declaration().as_entity()->attribute_count(); for (unsigned i = 0; i < n; ++i) { try { instance->get_attribute_value(i); } catch (const std::exception&) { - Logger::Error("SER", 9, "Expected " + boost::lexical_cast(n) + " attributes for:", instance); + logger.Error("SER", 9, "Expected " + boost::lexical_cast(n) + " attributes for:", instance); break; } auto argument = instance->get_attribute_value(i); @@ -176,7 +176,7 @@ ptree* format_entity_instance(ifcopenshell::geometry::abstract_mapping* mapping, try { value = format_attribute(mapping, argument, argument_type, qualified_name); } catch (const std::exception& e) { - Logger::Error("SER", 10, e); + logger.Error("SER", 10, e); } if (value) { @@ -196,9 +196,9 @@ ptree* format_entity_instance(ifcopenshell::geometry::abstract_mapping* mapping, // Formats an entity instances as a ptree node, and insert into the DOM. Recurses // over the entity attributes and writes them as xml attributes of the node. -ptree* format_entity_instance(ifcopenshell::geometry::abstract_mapping* mapping, IfcUtil::IfcBaseEntity* instance, ptree& tree, bool as_link = false) { +ptree* format_entity_instance(Logger& logger, ifcopenshell::geometry::abstract_mapping* mapping, IfcUtil::IfcBaseEntity* instance, ptree& tree, bool as_link = false) { ptree child; - return format_entity_instance(mapping, instance, child, tree, as_link); + return format_entity_instance(logger, mapping, instance, child, tree, as_link); } std::string qualify_unrooted_instance(IfcUtil::IfcBaseInterface* inst) { @@ -208,18 +208,18 @@ std::string qualify_unrooted_instance(IfcUtil::IfcBaseInterface* inst) { // A function to be called recursively. Template specialization is used // to descend into decomposition, containment and property relationships. template -ptree* descend(ifcopenshell::geometry::abstract_mapping* mapping, A* instance, ptree& tree, IfcUtil::IfcBaseClass* parent=nullptr) { +ptree* descend(Logger& logger, ifcopenshell::geometry::abstract_mapping* mapping, A* instance, ptree& tree, IfcUtil::IfcBaseClass* parent=nullptr) { if (instance->declaration().is(IfcSchema::IfcObjectDefinition::Class())) { - return descend(mapping, instance->template as(), tree, parent); + return descend(logger, mapping, instance->template as(), tree, parent); } else { - return format_entity_instance(mapping, instance, tree); + return format_entity_instance(logger, mapping, instance, tree); } } // Returns related entity instances using IFC's objectified relationship // model. The second and third argument require a member function pointer. template -auto get_related(T* t, F f, G g) { +auto get_related(Logger& logger, T* t, F f, G g) { typename U::list::ptr li = (*t.*f)()->template as(); typename aggregate_of::ptr acc(new aggregate_of); for (typename U::list::it it = li->begin(); it != li->end(); ++it) { @@ -227,7 +227,7 @@ auto get_related(T* t, F f, G g) { try { acc->push((*u.*g)()->template as()); } catch (IfcParse::IfcException& e) { - Logger::Error("SER", 11, e); + logger.Error("SER", 11, e); } } return acc; @@ -236,7 +236,7 @@ auto get_related(T* t, F f, G g) { // Descends into the tree by recursing into IfcRelContainedInSpatialStructure, // IfcRelDecomposes, IfcRelDefinesByType, IfcRelDefinesByProperties relations. template <> -ptree* descend(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::IfcObjectDefinition* product, ptree& tree, IfcUtil::IfcBaseClass* parent) { +ptree* descend(Logger& logger, ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::IfcObjectDefinition* product, ptree& tree, IfcUtil::IfcBaseClass* parent) { if (product->declaration().is(IfcSchema::IfcElement::Class())) { auto voids = product->as()->FillsVoids(); if (voids && voids->size() == 1 && (*voids->begin())->RelatingOpeningElement() != parent) { @@ -245,15 +245,15 @@ ptree* descend(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::Ifc } } - ptree& child = *format_entity_instance(mapping, product, tree); + ptree& child = *format_entity_instance(logger, mapping, product, tree); if (product->declaration().is(IfcSchema::IfcOpeningElement::Class())) { IfcSchema::IfcOpeningElement* opening = product->as(); IfcSchema::IfcElement::list::ptr fills = get_related( - opening, &IfcSchema::IfcOpeningElement::HasFillings, &IfcSchema::IfcRelFillsElement::RelatedBuildingElement); + logger, opening, &IfcSchema::IfcOpeningElement::HasFillings, &IfcSchema::IfcRelFillsElement::RelatedBuildingElement); for (IfcSchema::IfcElement::list::it it = fills->begin(); it != fills->end(); ++it) { - descend(mapping, *it, child, product); + descend(logger, mapping, *it, child, product); } } @@ -262,40 +262,40 @@ ptree* descend(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::Ifc IfcSchema::IfcObjectDefinition::list::ptr elements = get_related - (structure, &IfcSchema::IfcSpatialStructureElement::ContainsElements, &IfcSchema::IfcRelContainedInSpatialStructure::RelatedElements); + (logger, structure, &IfcSchema::IfcSpatialStructureElement::ContainsElements, &IfcSchema::IfcRelContainedInSpatialStructure::RelatedElements); for (IfcSchema::IfcObjectDefinition::list::it it = elements->begin(); it != elements->end(); ++it) { - descend(mapping, *it, child, product); + descend(logger, mapping, *it, child, product); } } if (product->declaration().is(IfcSchema::IfcElement::Class())) { IfcSchema::IfcElement* element = static_cast(product); IfcSchema::IfcOpeningElement::list::ptr openings = get_related( - element, &IfcSchema::IfcElement::HasOpenings, &IfcSchema::IfcRelVoidsElement::RelatedOpeningElement); + logger, element, &IfcSchema::IfcElement::HasOpenings, &IfcSchema::IfcRelVoidsElement::RelatedOpeningElement); for (IfcSchema::IfcOpeningElement::list::it it = openings->begin(); it != openings->end(); ++it) { - descend(mapping, *it, child, product); + descend(logger, mapping, *it, child, product); } } #ifdef SCHEMA_IfcRelDecomposes_HAS_RelatedObjects IfcSchema::IfcObjectDefinition::list::ptr structures = get_related - (product, &IfcSchema::IfcObjectDefinition::IsDecomposedBy, &IfcSchema::IfcRelDecomposes::RelatedObjects); + (logger, product, &IfcSchema::IfcObjectDefinition::IsDecomposedBy, &IfcSchema::IfcRelDecomposes::RelatedObjects); #else IfcSchema::IfcObjectDefinition::list::ptr structures = get_related - (product, &IfcSchema::IfcObjectDefinition::IsDecomposedBy, &IfcSchema::IfcRelAggregates::RelatedObjects); + (logger, product, &IfcSchema::IfcObjectDefinition::IsDecomposedBy, &IfcSchema::IfcRelAggregates::RelatedObjects); structures->push(get_related - (product, &IfcSchema::IfcObjectDefinition::IsNestedBy, &IfcSchema::IfcRelNests::RelatedObjects)); + (logger, product, &IfcSchema::IfcObjectDefinition::IsNestedBy, &IfcSchema::IfcRelNests::RelatedObjects)); #endif for (IfcSchema::IfcObjectDefinition::list::it it = structures->begin(); it != structures->end(); ++it) { IfcSchema::IfcObjectDefinition* ob = *it; - descend(mapping, ob, child, product); + descend(logger, mapping, ob, child, product); } if (product->declaration().is(IfcSchema::IfcObject::Class())) { @@ -303,12 +303,12 @@ ptree* descend(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::Ifc IfcSchema::IfcPropertySetDefinition::list::ptr property_sets = get_related - (object, &IfcSchema::IfcObject::IsDefinedBy, &IfcSchema::IfcRelDefinesByProperties::RelatingPropertyDefinition); + (logger, object, &IfcSchema::IfcObject::IsDefinedBy, &IfcSchema::IfcRelDefinesByProperties::RelatingPropertyDefinition); #ifdef SCHEMAS_HAS_IfcPropertySetDefinitionSet aggregate_of::ptr property_set_sets = get_related - (object, &IfcSchema::IfcObject::IsDefinedBy, &IfcSchema::IfcRelDefinesByProperties::RelatingPropertyDefinition); + (logger, object, &IfcSchema::IfcObject::IsDefinedBy, &IfcSchema::IfcRelDefinesByProperties::RelatingPropertyDefinition); for (auto& s : *property_set_sets) { property_sets->push((decltype(property_sets))*s); @@ -318,25 +318,25 @@ ptree* descend(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::Ifc for (IfcSchema::IfcPropertySetDefinition::list::it it = property_sets->begin(); it != property_sets->end(); ++it) { IfcSchema::IfcPropertySetDefinition* pset = *it; if (pset->declaration().is(IfcSchema::IfcPropertySet::Class())) { - format_entity_instance(mapping, pset, child, true); + format_entity_instance(logger, mapping, pset, child, true); } else if (pset->declaration().is(IfcSchema::IfcElementQuantity::Class())) { - format_entity_instance(mapping, pset, child, true); + format_entity_instance(logger, mapping, pset, child, true); } } #ifdef SCHEMA_IfcObject_HAS_IsTypedBy IfcSchema::IfcTypeObject::list::ptr types = get_related - (object, &IfcSchema::IfcObject::IsTypedBy, &IfcSchema::IfcRelDefinesByType::RelatingType); + (logger, object, &IfcSchema::IfcObject::IsTypedBy, &IfcSchema::IfcRelDefinesByType::RelatingType); #else IfcSchema::IfcTypeObject::list::ptr types = get_related - (object, &IfcSchema::IfcObject::IsDefinedBy, &IfcSchema::IfcRelDefinesByType::RelatingType); + (logger, object, &IfcSchema::IfcObject::IsDefinedBy, &IfcSchema::IfcRelDefinesByType::RelatingType); #endif for (IfcSchema::IfcTypeObject::list::it it = types->begin(); it != types->end(); ++it) { IfcSchema::IfcTypeObject* type = *it; - format_entity_instance(mapping, type, child, true); + format_entity_instance(logger, mapping, type, child, true); } } @@ -348,7 +348,7 @@ ptree* descend(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::Ifc // for the format_entity_instance() call. ptree node; node.put(".xlink:href", "#" + it->first); - format_entity_instance(mapping, it->second, node, child, true); + format_entity_instance(logger, mapping, it->second, node, child, true); } IfcSchema::IfcRelAssociates::list::ptr associations = product->HasAssociations(); @@ -357,7 +357,7 @@ ptree* descend(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::Ifc IfcSchema::IfcMaterialSelect* mat = (*it)->as()->RelatingMaterial(); ptree node; node.put(".xlink:href", "#" + qualify_unrooted_instance(mat)); - format_entity_instance(mapping, mat->as(), node, child, true); + format_entity_instance(logger, mapping, mat->as(), node, child, true); } } } @@ -365,7 +365,7 @@ ptree* descend(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::Ifc #if defined(SCHEMA_HAS_IfcAlignmentSegment) && defined(SCHEMA_IfcAlignmentSegment_HAS_DesignParameters) if (auto* als = product->as()) { ptree node; - format_entity_instance(mapping, als->DesignParameters(), node, child, false); + format_entity_instance(logger, mapping, als->DesignParameters(), node, child, false); } #endif @@ -373,19 +373,19 @@ ptree* descend(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::Ifc } // Format IfcProperty instances and insert into the DOM. IfcComplexProperties are flattened out. -void format_properties(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::IfcProperty::list::ptr properties, ptree& node) { +void format_properties(Logger& logger, ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::IfcProperty::list::ptr properties, ptree& node) { for (IfcSchema::IfcProperty::list::it it = properties->begin(); it != properties->end(); ++it) { IfcSchema::IfcProperty* p = *it; if (p->declaration().is(IfcSchema::IfcComplexProperty::Class())) { IfcSchema::IfcComplexProperty* complex = p->as(); - format_properties(mapping, complex->HasProperties(), node); + format_properties(logger, mapping, complex->HasProperties(), node); } else { - format_entity_instance(mapping, p, node); + format_entity_instance(logger, mapping, p, node); } } } -void writeGroupToNode(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::IfcGroup* group, ptree& node, std::setnotRootGroups) { +void writeGroupToNode(Logger& logger, ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::IfcGroup* group, ptree& node, std::setnotRootGroups) { // @todo tfk: instead of a set shouldn't we just have a set, the current approach // might not work with non-unique or NIL group names. @@ -398,7 +398,7 @@ void writeGroupToNode(ifcopenshell::geometry::abstract_mapping* mapping, IfcSche return; } // Write one group to root - ptree* node2 = descend(mapping, group, node); + ptree* node2 = descend(logger, mapping, group, node); auto father = group->IsGroupedBy(); for (auto iter = father->begin(); iter != father->end(); iter++) { @@ -407,39 +407,39 @@ void writeGroupToNode(ifcopenshell::geometry::abstract_mapping* mapping, IfcSche for (auto objit = objs->begin(); objit != objs->end(); objit++) { auto entity = *objit; if (entity->declaration().is(IfcSchema::IfcGroup::Class()) && entity->Name()) { - writeGroupToNode(mapping, entity->as(), *node2, notRootGroups); + writeGroupToNode(logger, mapping, entity->as(), *node2, notRootGroups); notRootGroups.emplace(*entity->Name()); } else { // Write child to father group - descend(mapping, entity, *node2); + descend(logger, mapping, entity, *node2); } } } } // Format IfcElementQuantity instances and insert into the DOM. -void format_quantities(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::IfcPhysicalQuantity::list::ptr quantities, ptree& node) { +void format_quantities(Logger& logger, ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::IfcPhysicalQuantity::list::ptr quantities, ptree& node) { for (IfcSchema::IfcPhysicalQuantity::list::it it = quantities->begin(); it != quantities->end(); ++it) { IfcSchema::IfcPhysicalQuantity* p = *it; - ptree* node2 = format_entity_instance(mapping, p, node); + ptree* node2 = format_entity_instance(logger, mapping, p, node); if (node2 && p->declaration().is(IfcSchema::IfcPhysicalComplexQuantity::Class())) { IfcSchema::IfcPhysicalComplexQuantity* complex = p->as(); - format_quantities(mapping, complex->HasQuantities(), *node2); + format_quantities(logger, mapping, complex->HasQuantities(), *node2); } } } // Format IfcTask instances and insert into the DOM. -void format_tasks(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::IfcTask* task, ptree& node) { - ptree* ntask = format_entity_instance(mapping, task, node); +void format_tasks(Logger& logger, ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::IfcTask* task, ptree& node) { + ptree* ntask = format_entity_instance(logger, mapping, task, node); if (ntask) { #ifdef SCHEMA_IfcTask_HAS_TaskTime IfcSchema::IfcTaskTime* task_time = task->TaskTime(); if (task_time) { - format_entity_instance(mapping, task_time, *ntask); + format_entity_instance(logger, mapping, task_time, *ntask); } #endif @@ -467,15 +467,15 @@ void format_tasks(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema:: IfcSchema::IfcPropertySetDefinition::list::ptr property_sets = get_related - (task, &IfcSchema::IfcObject::IsDefinedBy, &IfcSchema::IfcRelDefinesByProperties::RelatingPropertyDefinition); + (logger, task, &IfcSchema::IfcObject::IsDefinedBy, &IfcSchema::IfcRelDefinesByProperties::RelatingPropertyDefinition); for (IfcSchema::IfcPropertySetDefinition::list::it it = property_sets->begin(); it != property_sets->end(); ++it) { IfcSchema::IfcPropertySetDefinition* pset = *it; if (pset->declaration().is(IfcSchema::IfcPropertySet::Class())) { - format_entity_instance(mapping, pset, *ntask, true); + format_entity_instance(logger, mapping, pset, *ntask, true); } else if (pset->declaration().is(IfcSchema::IfcElementQuantity::Class())) { - format_entity_instance(mapping, pset, *ntask, true); + format_entity_instance(logger, mapping, pset, *ntask, true); } } @@ -538,7 +538,7 @@ void format_tasks(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema:: continue; } IfcSchema::IfcTask* task2 = (*it2)->as(); - format_tasks(mapping, task2, *ntask); + format_tasks(logger, mapping, task2, *ntask); } } #endif @@ -552,7 +552,7 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() { IfcSchema::IfcProject::list::ptr projects = file->instances_by_type(); if (projects->size() != 1) { - Logger::Message(Logger::LOG_ERROR, "SER", 12, "Expected a single IfcProject"); + logger_.Message(Logger::LOG_ERROR, "SER", 12, "Expected a single IfcProject"); return; } IfcSchema::IfcProject* project = *projects->begin(); @@ -563,7 +563,7 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() { try { return fn(); } catch(const std::exception& e) { - Logger::Error("SER", 13, e); + logger_.Error("SER", 13, e); static std::invoke_result_t v; return v; } @@ -588,7 +588,7 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() { catch (const IfcParse::IfcException& ex) { std::stringstream ss; ss << "Failed to get ifc file header file_description implementation_level, error: '" << ex.what() << "'"; - Logger::Message(Logger::LOG_ERROR, "SER", 14, ss.str()); + logger_.Message(Logger::LOG_ERROR, "SER", 14, ss.str()); } try { header.put("file_name.name", file->header().file_name()->name()); @@ -596,7 +596,7 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() { catch (const IfcParse::IfcException& ex) { std::stringstream ss; ss << "Failed to get ifc file header file_name name, error: '" << ex.what() << "'"; - Logger::Message(Logger::LOG_ERROR, "SER", 15, ss.str()); + logger_.Message(Logger::LOG_ERROR, "SER", 15, ss.str()); } try { header.put("file_name.time_stamp", file->header().file_name()->time_stamp()); @@ -604,7 +604,7 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() { catch (const IfcParse::IfcException& ex) { std::stringstream ss; ss << "Failed to get ifc file header file_name time_stamp, error: '" << ex.what() << "'"; - Logger::Message(Logger::LOG_ERROR, "SER", 16, ss.str()); + logger_.Message(Logger::LOG_ERROR, "SER", 16, ss.str()); } try { header.put("file_name.preprocessor_version", file->header().file_name()->preprocessor_version()); @@ -612,7 +612,7 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() { catch (const IfcParse::IfcException& ex) { std::stringstream ss; ss << "Failed to get ifc file header file_name preprocessor_version, error: '" << ex.what() << "'"; - Logger::Message(Logger::LOG_ERROR, "SER", 17, ss.str()); + logger_.Message(Logger::LOG_ERROR, "SER", 17, ss.str()); } try { header.put("file_name.originating_system", file->header().file_name()->originating_system()); @@ -620,7 +620,7 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() { catch (const IfcParse::IfcException& ex) { std::stringstream ss; ss << "Failed to get ifc file header file_name originating_system, error: '" << ex.what() << "'"; - Logger::Message(Logger::LOG_ERROR, "SER", 18, ss.str()); + logger_.Message(Logger::LOG_ERROR, "SER", 18, ss.str()); } try { // @nb inconsistent spelling @@ -629,19 +629,19 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() { catch (const IfcParse::IfcException& ex) { std::stringstream ss; ss << "Failed to get ifc file header file_name authorization, error: '" << ex.what() << "'"; - Logger::Message(Logger::LOG_ERROR, "SER", 19, ss.str()); - } + logger_.Message(Logger::LOG_ERROR, "SER", 19, ss.str()); + } // Descend into the decomposition structure of the IFC file. - descend(mapping_, project, decomposition); + descend(logger_, mapping_, project, decomposition); // Write all property sets and values as XML nodes. IfcSchema::IfcPropertySet::list::ptr psets = file->instances_by_type(); for (IfcSchema::IfcPropertySet::list::it it = psets->begin(); it != psets->end(); ++it) { IfcSchema::IfcPropertySet* pset = *it; - ptree* node = format_entity_instance(mapping_, pset, properties); + ptree* node = format_entity_instance(logger_, mapping_, pset, properties); if (node) { - format_properties(mapping_, pset->HasProperties(), *node); + format_properties(logger_, mapping_, pset->HasProperties(), *node); } } @@ -649,7 +649,7 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() { IfcSchema::IfcGroup::list::ptr gsets = file->instances_by_type(); std::set notRootGroups; //selfname, fathername for (IfcSchema::IfcGroup::list::it it = gsets->begin(); it != gsets->end(); ++it) { - writeGroupToNode(mapping_, *it, groups, notRootGroups); + writeGroupToNode(logger_, mapping_, *it, groups, notRootGroups); } for (auto it = groups.begin(); it != groups.end();) { if (notRootGroups.find(it->second.get(".Name")) != notRootGroups.end()) { @@ -663,9 +663,9 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() { IfcSchema::IfcElementQuantity::list::ptr qtosets = file->instances_by_type(); for (IfcSchema::IfcElementQuantity::list::it it = qtosets->begin(); it != qtosets->end(); ++it) { IfcSchema::IfcElementQuantity* qto = *it; - ptree* node = format_entity_instance(mapping_, qto, quantities); + ptree* node = format_entity_instance(logger_, mapping_, qto, quantities); if (node) { - format_quantities(mapping_, qto->Quantities(), *node); + format_quantities(logger_, mapping_, qto->Quantities(), *node); } } @@ -673,8 +673,8 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() { ptree pwork_schedules; IfcSchema::IfcWorkSchedule::list::ptr pschedules = file->instances_by_type(); for (IfcSchema::IfcWorkSchedule::list::it it = pschedules->begin(); it != pschedules->end(); ++it) { - IfcSchema::IfcWorkSchedule* schedule = *it; - ptree* nschedule = format_entity_instance(mapping_, schedule, pwork_schedules); + IfcSchema::IfcWorkSchedule* schedule = *it; + ptree* nschedule = format_entity_instance(logger_, mapping_, schedule, pwork_schedules); if(nschedule) { IfcSchema::IfcRelAssignsToControl::list::ptr controls = schedule->Controls(); @@ -687,7 +687,7 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() { if (object && object->declaration().is(IfcSchema::IfcTask::Class())) { IfcSchema::IfcTask* task = object->as(); - format_tasks(mapping_, task, *nschedule); + format_tasks(logger_, mapping_, task, *nschedule); } } } @@ -700,7 +700,7 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() { IfcSchema::IfcWorkPlan::list::ptr pplans = file->instances_by_type(); for (IfcSchema::IfcWorkPlan::list::it it = pplans->begin(); it != pplans->end(); ++it) { IfcSchema::IfcWorkPlan* plan = *it; - ptree* nschedule = format_entity_instance(mapping_, plan, pwork_plans); + ptree* nschedule = format_entity_instance(logger_, mapping_, plan, pwork_plans); if (nschedule) { #ifdef SCHEMA_IfcObjectDefinition_HAS_IsDecomposedBy @@ -725,8 +725,8 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() { #ifdef SCHEMA_HAS_IfcWorkCalendar IfcSchema::IfcWorkCalendar::list::ptr pcalendars = file->instances_by_type(); for (IfcSchema::IfcWorkCalendar::list::it it = pcalendars->begin(); it != pcalendars->end(); ++it) { - IfcSchema::IfcWorkCalendar* calendar = *it; - ptree* ncalendar = format_entity_instance(mapping_, calendar, calendars); + IfcSchema::IfcWorkCalendar* calendar = *it; + ptree* ncalendar = format_entity_instance(logger_, mapping_, calendar, calendars); if (ncalendar) { IfcSchema::IfcWorkTime::list::ptr working_times = calendar->WorkingTimes().value_or(nullptr); @@ -734,7 +734,7 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() { for (IfcSchema::IfcWorkTime::list::it it2 = working_times->begin(); it2 != working_times->end(); ++it2) { IfcSchema::IfcWorkTime* working_time = *it2; - format_entity_instance(mapping_, working_time, *ncalendar); + format_entity_instance(logger_, mapping_, working_time, *ncalendar); } } } @@ -745,13 +745,13 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() { for (IfcSchema::IfcRelConnectsElements::list::it it = pconnections->begin(); it != pconnections->end(); ++it) { IfcSchema::IfcRelConnectsElements* connection = *it; - ptree* nconnection = format_entity_instance(mapping_, connection, connections); + ptree* nconnection = format_entity_instance(logger_, mapping_, connection, connections); ptree nrelatedElement; ptree nrelatingElement; - format_entity_instance(mapping_,connection->RelatedElement(), nrelatedElement, true); - format_entity_instance(mapping_,connection->RelatingElement(), nrelatingElement, true); + format_entity_instance(logger_, mapping_, connection->RelatedElement(), nrelatedElement, true); + format_entity_instance(logger_, mapping_, connection->RelatingElement(), nrelatingElement, true); nconnection->add_child("RelatedElement", nrelatedElement); nconnection->add_child("RelatingElement", nrelatingElement); @@ -761,14 +761,14 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() { IfcSchema::IfcTypeObject::list::ptr type_objects = file->instances_by_type(); for (IfcSchema::IfcTypeObject::list::it it = type_objects->begin(); it != type_objects->end(); ++it) { IfcSchema::IfcTypeObject* type_object = *it; - ptree* node = descend(mapping_, type_object, types); + ptree* node = descend(logger_, mapping_, type_object, types); if (node && type_object->HasPropertySets()) { IfcSchema::IfcPropertySetDefinition::list::ptr property_sets = *type_object->HasPropertySets(); for (IfcSchema::IfcPropertySetDefinition::list::it jt = property_sets->begin(); jt != property_sets->end(); ++jt) { IfcSchema::IfcPropertySetDefinition* pset = *jt; if (pset->declaration().is(IfcSchema::IfcPropertySet::Class())) { - format_entity_instance(mapping_, pset, *node, true); + format_entity_instance(logger_, mapping_, pset, *node, true); } } } @@ -779,12 +779,12 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() { for (auto it = unit_assignments->begin(); it != unit_assignments->end(); ++it) { if ((*it)->declaration().is(IfcSchema::IfcNamedUnit::Class())) { IfcSchema::IfcNamedUnit* named_unit = (*it)->as(); - ptree* node = format_entity_instance(mapping_, named_unit, units); + ptree* node = format_entity_instance(logger_, mapping_, named_unit, units); if (node) { node->put(".SI_equivalent", IfcParse::get_SI_equivalent(named_unit)); } } else if ((*it)->declaration().is(IfcSchema::IfcMonetaryUnit::Class())) { - format_entity_instance(mapping_, (*it)->as(), units); + format_entity_instance(logger_, mapping_, (*it)->as(), units); } } @@ -799,7 +799,7 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() { layer_names.insert(name); ptree node; node.put(".id", name); - format_entity_instance(mapping_, *it, node, layers); + format_entity_instance(logger_, mapping_, *it, node, layers); } } @@ -825,16 +825,16 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() { if ((*jt)->Material()) { subnode.put(".Name", (*jt)->Material()->Name()); } - format_entity_instance(mapping_, *jt, subnode, node); + format_entity_instance(logger_, mapping_, *jt, subnode, node); } } else if (mat->as()) { IfcSchema::IfcMaterial::list::ptr mats = mat->as()->Materials(); for (IfcSchema::IfcMaterial::list::it jt = mats->begin(); jt != mats->end(); ++jt) { ptree subnode; - format_entity_instance(mapping_, *jt, subnode, node); + format_entity_instance(logger_, mapping_, *jt, subnode, node); } } - format_entity_instance(mapping_, mat->as(), node, materials); + format_entity_instance(logger_, mapping_, mat->as(), node, materials); } } diff --git a/src/serializers/schema_dependent/XmlSerializer.h b/src/serializers/schema_dependent/XmlSerializer.h index a404c45cb7..2c63ee6e2e 100644 --- a/src/serializers/schema_dependent/XmlSerializer.h +++ b/src/serializers/schema_dependent/XmlSerializer.h @@ -39,9 +39,9 @@ private: ifcopenshell::geometry::abstract_mapping* mapping_; public: - POSTFIX_SCHEMA(XmlSerializer)(IfcParse::IfcFile* file, const std::string& xml_filename) - : XmlSerializer(0, "") - , mapping_(ifcopenshell::geometry::impl::mapping_implementations().construct(file, settings_)) + POSTFIX_SCHEMA(XmlSerializer)(IfcParse::IfcFile* file, const std::string& xml_filename, Logger& logger = Logger::Root()) + : XmlSerializer(0, "", logger) + , mapping_(ifcopenshell::geometry::impl::mapping_implementations().construct(file, settings_, logger)) { this->file = file; this->xml_filename = xml_filename; @@ -51,4 +51,4 @@ public: void setFile(IfcParse::IfcFile*) {} }; -#endif \ No newline at end of file +#endif