mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-06 07:51:47 +00:00
More logger changes
This commit is contained in:
@@ -1279,11 +1279,11 @@ bool init_input_file(const std::string& filename, IfcParse::IfcFile*& ifc_file,
|
||||
|
||||
#ifdef WITH_IFCXML
|
||||
if (boost::ends_with(boost::to_lower_copy(filename), ".ifcxml")) {
|
||||
ifc_file = IfcParse::parse_ifcxml(filename);
|
||||
ifc_file = IfcParse::parse_ifcxml(filename, logger);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ifc_file = new IfcParse::IfcFile(IfcParse::uninitialized_tag{});
|
||||
ifc_file = new IfcParse::IfcFile(IfcParse::uninitialized_tag{}, logger);
|
||||
requires_init = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ namespace ifcopenshell {
|
||||
const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes) = 0;
|
||||
virtual bool unify_shapes(const IfcGeom::ConversionResults&, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
|
||||
|
||||
virtual AbstractKernel* clone() const = 0;
|
||||
virtual AbstractKernel* clone(Logger& logger) const = 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+40
-17
@@ -167,7 +167,15 @@ bool IfcGeom::Iterator::initialize() {
|
||||
return *initialization_outcome_;
|
||||
}
|
||||
|
||||
void IfcGeom::Iterator::process_finished_rep(geometry_conversion_result* rep) {
|
||||
void IfcGeom::Iterator::flush_worker_log(ifcopenshell::geometry::Converter* kernel) {
|
||||
if (kernel && &kernel->logger() != &logger_) {
|
||||
logger_.Append(kernel->logger());
|
||||
}
|
||||
}
|
||||
|
||||
void IfcGeom::Iterator::process_finished_rep(geometry_conversion_result* rep, ifcopenshell::geometry::Converter* kernel) {
|
||||
flush_worker_log(kernel);
|
||||
|
||||
if (rep->elements.empty()) {
|
||||
return;
|
||||
}
|
||||
@@ -193,8 +201,17 @@ void IfcGeom::Iterator::process_concurrently() {
|
||||
}
|
||||
|
||||
kernel_pool.reserve(conc_threads);
|
||||
worker_loggers_.reserve(conc_threads);
|
||||
for (unsigned i = 0; i < conc_threads; ++i) {
|
||||
kernel_pool.push_back(new ifcopenshell::geometry::Converter(std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel>(converter_->kernel()->clone()), ifc_file, settings_, logger_));
|
||||
worker_loggers_.emplace_back(std::make_unique<Logger>());
|
||||
Logger& worker_logger = *worker_loggers_.back();
|
||||
worker_logger.Verbosity(logger_.Verbosity());
|
||||
worker_logger.OutputFormat(logger_.OutputFormat());
|
||||
worker_logger.PrintPerformanceStatsOnElement(logger_.PrintPerformanceStatsOnElement());
|
||||
if (worker_logger.OutputFormat() != Logger::FMT_INMEMORY) {
|
||||
worker_logger.SetOutput(static_cast<std::ostream*>(nullptr), static_cast<std::ostream*>(nullptr));
|
||||
}
|
||||
kernel_pool.push_back(new ifcopenshell::geometry::Converter(std::unique_ptr<ifcopenshell::geometry::kernels::AbstractKernel>(converter_->kernel()->clone(worker_logger)), ifc_file, settings_, worker_logger));
|
||||
}
|
||||
|
||||
std::vector<std::future<geometry_conversion_result*>> threadpool;
|
||||
@@ -211,11 +228,12 @@ void IfcGeom::Iterator::process_concurrently() {
|
||||
std::future_status status;
|
||||
status = fu.wait_for(std::chrono::seconds(0));
|
||||
if (status == std::future_status::ready) {
|
||||
process_finished_rep(fu.get());
|
||||
process_finished_rep(fu.get(), kernel_pool[i]);
|
||||
|
||||
std::swap(threadpool[i], threadpool.back());
|
||||
threadpool.pop_back();
|
||||
std::swap(kernel_pool[i], kernel_pool.back());
|
||||
std::swap(worker_loggers_[i], worker_loggers_.back());
|
||||
K = kernel_pool.back();
|
||||
break;
|
||||
} // if
|
||||
@@ -231,14 +249,14 @@ void IfcGeom::Iterator::process_concurrently() {
|
||||
try {
|
||||
this->create_element_(kernel, settings, rep);
|
||||
} catch (const std::exception& e) {
|
||||
logger_.Error("GEO", 52,
|
||||
kernel->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,
|
||||
kernel->logger().Error("GEO", 53,
|
||||
"Unknown exception occurred while iteartor was creating a shape: ",
|
||||
rep->item->instance
|
||||
);
|
||||
@@ -257,8 +275,8 @@ void IfcGeom::Iterator::process_concurrently() {
|
||||
threadpool.emplace_back(std::move(fu));
|
||||
}
|
||||
|
||||
for (auto& fu : threadpool) {
|
||||
process_finished_rep(fu.get());
|
||||
for (size_t i = 0; i < threadpool.size(); ++i) {
|
||||
process_finished_rep(threadpool[i].get(), kernel_pool[i]);
|
||||
}
|
||||
|
||||
finished_ = true;
|
||||
@@ -344,6 +362,8 @@ const IfcUtil::IfcBaseClass* IfcGeom::Iterator::create_shape_model_for_next_enti
|
||||
|
||||
void IfcGeom::Iterator::create_element_(ifcopenshell::geometry::Converter* kernel, ifcopenshell::geometry::Settings settings, geometry_conversion_result* rep)
|
||||
{
|
||||
Logger& kernel_logger = kernel->logger();
|
||||
|
||||
if (!settings_.get<ifcopenshell::geometry::settings::NoParallelMapping>().get()) {
|
||||
rep->item = kernel->mapping()->map(rep->representation);
|
||||
if (!rep->item) {
|
||||
@@ -360,20 +380,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);
|
||||
kernel_logger.SetProduct(product);
|
||||
|
||||
IfcGeom::BRepElement* brep = static_cast<IfcGeom::BRepElement*>(decorate_with_cache_(GeometrySerializer::READ_BREP, (std::string)product->get("GlobalId"), std::to_string(rep->item->instance->as<IfcUtil::IfcBaseEntity>()->id()), [kernel, settings, product, place, rep]() {
|
||||
return kernel->create_brep_for_representation_and_product(rep->item, product, place);
|
||||
}));
|
||||
|
||||
if (!brep) {
|
||||
logger_.SetProduct(boost::none);
|
||||
kernel_logger.SetProduct(boost::none);
|
||||
return;
|
||||
}
|
||||
|
||||
auto elem = process_based_on_settings(settings, brep);
|
||||
auto elem = process_based_on_settings(settings, brep, kernel_logger);
|
||||
if (!elem) {
|
||||
logger_.SetProduct(boost::none);
|
||||
kernel_logger.SetProduct(boost::none);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -385,11 +405,13 @@ void IfcGeom::Iterator::create_element_(ifcopenshell::geometry::Converter* kerne
|
||||
const IfcUtil::IfcBaseEntity* product2 = p.first;
|
||||
const auto& place2 = p.second;
|
||||
|
||||
kernel_logger.SetProduct(product2);
|
||||
|
||||
IfcGeom::BRepElement* brep2 = static_cast<IfcGeom::BRepElement*>(decorate_with_cache_(GeometrySerializer::READ_BREP, (std::string)product2->get("GlobalId"), std::to_string(rep->item->instance->as<IfcUtil::IfcBaseEntity>()->id()), [kernel, settings, product2, place2, brep]() {
|
||||
return kernel->create_brep_for_processed_representation(product2, place2, brep);
|
||||
}));
|
||||
if (brep2) {
|
||||
auto elem2 = process_based_on_settings(settings, brep2, dynamic_cast<IfcGeom::TriangulationElement*>(elem));
|
||||
auto elem2 = process_based_on_settings(settings, brep2, kernel_logger, dynamic_cast<IfcGeom::TriangulationElement*>(elem));
|
||||
if (elem2) {
|
||||
rep->breps.push_back(brep2);
|
||||
rep->elements.push_back(elem2);
|
||||
@@ -397,16 +419,16 @@ void IfcGeom::Iterator::create_element_(ifcopenshell::geometry::Converter* kerne
|
||||
}
|
||||
}
|
||||
|
||||
logger_.SetProduct(boost::none);
|
||||
kernel_logger.SetProduct(boost::none);
|
||||
}
|
||||
|
||||
IfcGeom::Element* IfcGeom::Iterator::process_based_on_settings(ifcopenshell::geometry::Settings settings, IfcGeom::BRepElement* elem, IfcGeom::TriangulationElement* previous)
|
||||
IfcGeom::Element* IfcGeom::Iterator::process_based_on_settings(ifcopenshell::geometry::Settings settings, IfcGeom::BRepElement* elem, Logger& logger, IfcGeom::TriangulationElement* previous)
|
||||
{
|
||||
if (settings.get<ifcopenshell::geometry::settings::IteratorOutput>().get() == ifcopenshell::geometry::settings::SERIALIZED) {
|
||||
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<ifcopenshell::geometry::settings::IteratorOutput>().get() == ifcopenshell::geometry::settings::TRIANGULATED) {
|
||||
@@ -417,7 +439,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, [this, elem, previous]() {
|
||||
return decorate_with_cache_(GeometrySerializer::READ_TRIANGULATION, elem->guid(), gid2, [&logger, elem, previous]() {
|
||||
try {
|
||||
if (!previous) {
|
||||
return new TriangulationElement(*elem);
|
||||
@@ -425,7 +447,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;
|
||||
});
|
||||
@@ -824,6 +846,7 @@ IfcGeom::Iterator::~Iterator() {
|
||||
}
|
||||
|
||||
for (auto& k : kernel_pool) {
|
||||
flush_worker_log(k);
|
||||
delete k;
|
||||
}
|
||||
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
|
||||
namespace IfcGeom {
|
||||
|
||||
@@ -133,6 +134,7 @@ namespace IfcGeom {
|
||||
|
||||
// When multi-threaded
|
||||
std::vector<ifcopenshell::geometry::Converter*> kernel_pool;
|
||||
std::vector<std::unique_ptr<Logger>> worker_loggers_;
|
||||
|
||||
// The object is fetched beforehand to be sure that get() returns a valid element
|
||||
TriangulationElement* current_triangulation;
|
||||
@@ -200,8 +202,11 @@ namespace IfcGeom {
|
||||
IfcGeom::Element* process_based_on_settings(
|
||||
ifcopenshell::geometry::Settings settings,
|
||||
IfcGeom::BRepElement* elem,
|
||||
Logger& logger,
|
||||
IfcGeom::TriangulationElement* previous = nullptr);
|
||||
|
||||
void flush_worker_log(ifcopenshell::geometry::Converter* kernel);
|
||||
|
||||
bool wait_for_element();
|
||||
|
||||
void log_timepoints() const;
|
||||
@@ -293,7 +298,7 @@ namespace IfcGeom {
|
||||
|
||||
size_t processed_ = 0;
|
||||
|
||||
void process_finished_rep(geometry_conversion_result* rep);
|
||||
void process_finished_rep(geometry_conversion_result* rep, ifcopenshell::geometry::Converter* kernel = nullptr);
|
||||
|
||||
void process_concurrently();
|
||||
|
||||
|
||||
@@ -156,14 +156,14 @@ namespace ifcopenshell {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
virtual AbstractKernel* clone() const
|
||||
virtual AbstractKernel* clone(Logger& logger) const
|
||||
{
|
||||
std::vector<std::unique_ptr<AbstractKernel>> ks;
|
||||
for (auto& k : kernels_) {
|
||||
ks.emplace_back(k->clone());
|
||||
ks.emplace_back(k->clone(logger));
|
||||
}
|
||||
// @todo ugly
|
||||
return new HybridKernel(geometry_library(), file_, const_cast<Settings&>(settings()), std::move(ks), logger());
|
||||
return new HybridKernel(geometry_library(), file_, const_cast<Settings&>(settings()), std::move(ks), logger);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/********************************************************************************
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
@@ -162,13 +162,13 @@ CGAL::Nef_polyhedron_3<Kernel_> 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();
|
||||
}
|
||||
}
|
||||
@@ -197,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<std::string>(density), l->instance);
|
||||
logger().Notice("GEO", 77, "Density " + boost::lexical_cast<std::string>(density), l->instance);
|
||||
if (density > 5000) {
|
||||
logger_.Notice("GEO", 78, "Substituted element with " + boost::lexical_cast<std::string>(density) + " vertices / m3 with a bounding box");
|
||||
logger().Notice("GEO", 78, "Substituted element with " + boost::lexical_cast<std::string>(density) + " vertices / m3 with a bounding box");
|
||||
CGAL::Point_3<Kernel_> lower(minmax.first(0), minmax.first(1), minmax.first(2));
|
||||
CGAL::Point_3<Kernel_> upper(minmax.second(0), minmax.second(1), minmax.second(2));
|
||||
shape = utils::create_cube(lower, upper);
|
||||
@@ -215,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;
|
||||
}
|
||||
|
||||
@@ -237,7 +237,7 @@ bool CgalKernel::convert(const taxonomy::face::ptr face, std::list<cgal_face_t>&
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -250,7 +250,7 @@ bool CgalKernel::convert(const taxonomy::face::ptr face, std::list<cgal_face_t>&
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -704,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -718,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;
|
||||
}
|
||||
|
||||
@@ -729,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<cgal_point_t> 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;
|
||||
@@ -758,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;
|
||||
}
|
||||
|
||||
@@ -786,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;
|
||||
}
|
||||
|
||||
@@ -820,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;
|
||||
@@ -965,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;
|
||||
}
|
||||
|
||||
@@ -1190,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<settings::Precision>().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;
|
||||
}
|
||||
|
||||
@@ -1326,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;
|
||||
}
|
||||
|
||||
@@ -1341,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;
|
||||
}
|
||||
|
||||
@@ -1424,8 +1424,8 @@ bool CgalKernel::preprocess_boolean_operand(const IfcUtil::IfcBaseClass* log_ref
|
||||
try {
|
||||
result = CGAL::Nef_polyhedron_3<Kernel_>(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;
|
||||
}
|
||||
|
||||
@@ -1497,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;
|
||||
}
|
||||
}
|
||||
@@ -1523,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;
|
||||
@@ -1846,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<Kernel_> result;
|
||||
auto it = loops.begin();
|
||||
@@ -1899,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;
|
||||
|
||||
@@ -1985,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;
|
||||
}
|
||||
|
||||
@@ -2131,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -97,8 +97,8 @@ namespace ifcopenshell {
|
||||
: AbstractKernel("cgal", settings, logger)
|
||||
{}
|
||||
|
||||
virtual AbstractKernel* clone() const {
|
||||
return new CgalKernel(settings(), logger());
|
||||
virtual AbstractKernel* clone(Logger& logger) const {
|
||||
return new CgalKernel(settings(), logger);
|
||||
}
|
||||
|
||||
virtual bool supports_boolean_operations() const {
|
||||
|
||||
@@ -118,8 +118,8 @@ public:
|
||||
, precision_(settings.get<ifcopenshell::geometry::settings::Precision>().get())
|
||||
{}
|
||||
|
||||
virtual AbstractKernel* clone() const {
|
||||
return new OpenCascadeKernel(settings(), logger());
|
||||
virtual AbstractKernel* clone(Logger& logger) const {
|
||||
return new OpenCascadeKernel(settings(), logger);
|
||||
}
|
||||
|
||||
virtual bool supports_boolean_operations() const { return true; }
|
||||
|
||||
@@ -216,6 +216,7 @@ struct cant_curve_segment_function {
|
||||
class curve_segment_evaluator {
|
||||
private:
|
||||
mapping* mapping_ = nullptr;
|
||||
Logger& logger_;
|
||||
const IfcSchema::IfcCurveSegment* inst_ = nullptr; // this curve segment instance
|
||||
double length_unit_;
|
||||
double start_;
|
||||
@@ -234,6 +235,7 @@ class curve_segment_evaluator {
|
||||
public:
|
||||
curve_segment_evaluator(mapping* mapping, const IfcSchema::IfcCurveSegment* inst, double length_unit)
|
||||
: mapping_(mapping),
|
||||
logger_(mapping->logger()),
|
||||
inst_(inst),
|
||||
length_unit_(length_unit),
|
||||
parent_curve_(inst->ParentCurve()) {
|
||||
@@ -1136,18 +1138,18 @@ class curve_segment_evaluator {
|
||||
// A numerical solution is required.
|
||||
// This functor finds the value of x such that s(x) - u = 0, where u is the input value and s is the
|
||||
// computed curve length.
|
||||
x_at_dist_along = [curve_length_fn,mapping=mapping_](double u) -> double {
|
||||
x_at_dist_along = [curve_length_fn, this](double u) -> double {
|
||||
std::uintmax_t max_iter = 9000;
|
||||
auto tol = [](double a, double b) { return fabs(b - a) < 1.0E-11; };
|
||||
auto x = u; // start by assuming u = x (it's not, but it will be close)
|
||||
try {
|
||||
// set up the root finding function that evaluates s(x) - u
|
||||
auto f = [curve_length_fn, u,mapping=mapping](double x) -> double { return curve_length_fn(x) - u; };
|
||||
auto f = [curve_length_fn, u](double x) -> double { return curve_length_fn(x) - u; };
|
||||
// use a root finder to get x
|
||||
auto result = boost::math::tools::bracket_and_solve_root(f, x, 2.0, true, tol, max_iter);
|
||||
x = result.first;
|
||||
} catch (...) {
|
||||
mapping->logger().Warning("GEO", 253, "root solver failed");
|
||||
logger_.Warning("GEO", 253, "root solver failed");
|
||||
}
|
||||
return x;
|
||||
};
|
||||
|
||||
@@ -119,11 +119,11 @@ std::tuple<typename aggregate_of<Ifc4x3_add2::IfcObjectDefinition>::ptr, typenam
|
||||
{
|
||||
auto pt = file.addDoublet<Ifc4x3_add2::IfcCartesianPoint>(xBT, yBT);
|
||||
auto design_parameters = new Ifc4x3_add2::IfcAlignmentHorizontalSegment(boost::none, boost::none, pt, angleBT, 0.0, 0.0, tangent_run, boost::none, Ifc4x3_add2::IfcAlignmentHorizontalSegmentTypeEnum::IfcAlignmentHorizontalSegmentType_LINE);
|
||||
auto alignment_segment = new Ifc4x3_add2::IfcAlignmentSegment(IfcParse::IfcGlobalId(), nullptr, boost::none, boost::none, boost::none, nullptr, nullptr, design_parameters);
|
||||
auto alignment_segment = new Ifc4x3_add2::IfcAlignmentSegment(IfcParse::IfcGlobalId(file.logger()), nullptr, boost::none, boost::none, boost::none, nullptr, nullptr, design_parameters);
|
||||
horizontal_segments->push(alignment_segment);
|
||||
|
||||
if (include_geometry) {
|
||||
horizontal_curve_segments->push(mapAlignmentHorizontalSegment(design_parameters).first);
|
||||
horizontal_curve_segments->push(mapAlignmentHorizontalSegment(design_parameters, file.logger()).first);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,11 +131,11 @@ std::tuple<typename aggregate_of<Ifc4x3_add2::IfcObjectDefinition>::ptr, typenam
|
||||
{
|
||||
auto pc = file.addDoublet<Ifc4x3_add2::IfcCartesianPoint>(xPC, yPC);
|
||||
auto design_parameters = new Ifc4x3_add2::IfcAlignmentHorizontalSegment(boost::none, boost::none, pc, angleBT, radius, radius, lc, boost::none, Ifc4x3_add2::IfcAlignmentHorizontalSegmentTypeEnum::IfcAlignmentHorizontalSegmentType_CIRCULARARC);
|
||||
auto alignment_segment = new Ifc4x3_add2::IfcAlignmentSegment(IfcParse::IfcGlobalId(), nullptr, boost::none, boost::none, boost::none, nullptr, nullptr, design_parameters);
|
||||
auto alignment_segment = new Ifc4x3_add2::IfcAlignmentSegment(IfcParse::IfcGlobalId(file.logger()), nullptr, boost::none, boost::none, boost::none, nullptr, nullptr, design_parameters);
|
||||
horizontal_segments->push(alignment_segment);
|
||||
|
||||
if (include_geometry) {
|
||||
horizontal_curve_segments->push(mapAlignmentHorizontalSegment(design_parameters).first);
|
||||
horizontal_curve_segments->push(mapAlignmentHorizontalSegment(design_parameters, file.logger()).first);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,19 +152,19 @@ std::tuple<typename aggregate_of<Ifc4x3_add2::IfcObjectDefinition>::ptr, typenam
|
||||
auto tangent_run = sqrt(dx * dx + dy * dy);
|
||||
auto pt = file.addDoublet<Ifc4x3_add2::IfcCartesianPoint>(xBT, yBT);
|
||||
auto design_parameters = new Ifc4x3_add2::IfcAlignmentHorizontalSegment(boost::none, boost::none, pt, angleBT, 0.0, 0.0, tangent_run, boost::none, Ifc4x3_add2::IfcAlignmentHorizontalSegmentTypeEnum::IfcAlignmentHorizontalSegmentType_LINE);
|
||||
auto alignment_segment = new Ifc4x3_add2::IfcAlignmentSegment(IfcParse::IfcGlobalId(), nullptr, boost::none, boost::none, boost::none, nullptr, nullptr, design_parameters);
|
||||
auto alignment_segment = new Ifc4x3_add2::IfcAlignmentSegment(IfcParse::IfcGlobalId(file.logger()), nullptr, boost::none, boost::none, boost::none, nullptr, nullptr, design_parameters);
|
||||
horizontal_segments->push(alignment_segment);
|
||||
if (include_geometry) {
|
||||
horizontal_curve_segments->push(mapAlignmentHorizontalSegment(design_parameters).first);
|
||||
horizontal_curve_segments->push(mapAlignmentHorizontalSegment(design_parameters, file.logger()).first);
|
||||
}
|
||||
|
||||
// create zero length terminator segment
|
||||
auto poe = file.addDoublet<Ifc4x3_add2::IfcCartesianPoint>(xPI, yPI);
|
||||
design_parameters = new Ifc4x3_add2::IfcAlignmentHorizontalSegment(boost::none, boost::none, poe, angleBT, 0.0, 0.0, 0.0, boost::none, Ifc4x3_add2::IfcAlignmentHorizontalSegmentTypeEnum::IfcAlignmentHorizontalSegmentType_LINE);
|
||||
alignment_segment = new Ifc4x3_add2::IfcAlignmentSegment(IfcParse::IfcGlobalId(), nullptr, boost::none, boost::none, boost::none, nullptr, nullptr, design_parameters);
|
||||
alignment_segment = new Ifc4x3_add2::IfcAlignmentSegment(IfcParse::IfcGlobalId(file.logger()), nullptr, boost::none, boost::none, boost::none, nullptr, nullptr, design_parameters);
|
||||
horizontal_segments->push(alignment_segment);
|
||||
if (include_geometry) {
|
||||
auto segment = mapAlignmentHorizontalSegment(design_parameters).first;
|
||||
auto segment = mapAlignmentHorizontalSegment(design_parameters, file.logger()).first;
|
||||
segment->setTransition(Ifc4x3_add2::IfcTransitionCode::IfcTransitionCode_DISCONTINUOUS);
|
||||
horizontal_curve_segments->push(segment);
|
||||
}
|
||||
@@ -186,10 +186,10 @@ Ifc4x3_add2::IfcAlignment* addHorizontalAlignment(IfcHierarchyHelper<Ifc4x3_add2
|
||||
//
|
||||
// Create the horizontal alignment (IfcAlignmentHorizontal) and nest alignment segments
|
||||
//
|
||||
auto horizontal_alignment = new Ifc4x3_add2::IfcAlignmentHorizontal(IfcParse::IfcGlobalId(), nullptr, alignment_name + std::string(" - Horizontal"), boost::none, boost::none, nullptr, nullptr);
|
||||
auto horizontal_alignment = new Ifc4x3_add2::IfcAlignmentHorizontal(IfcParse::IfcGlobalId(file.logger()), nullptr, alignment_name + std::string(" - Horizontal"), boost::none, boost::none, nullptr, nullptr);
|
||||
file.addEntity(horizontal_alignment);
|
||||
|
||||
auto nests_horizontal_segments = new Ifc4x3_add2::IfcRelNests(IfcParse::IfcGlobalId(), nullptr, boost::none, std::string("Nests horizontal alignment segments with horizontal alignment"), horizontal_alignment, horizontal_segments);
|
||||
auto nests_horizontal_segments = new Ifc4x3_add2::IfcRelNests(IfcParse::IfcGlobalId(file.logger()), nullptr, boost::none, std::string("Nests horizontal alignment segments with horizontal alignment"), horizontal_alignment, horizontal_segments);
|
||||
file.addEntity(nests_horizontal_segments);
|
||||
|
||||
//
|
||||
@@ -220,7 +220,7 @@ Ifc4x3_add2::IfcAlignment* addHorizontalAlignment(IfcHierarchyHelper<Ifc4x3_add2
|
||||
}
|
||||
|
||||
// create the alignment
|
||||
auto alignment = new Ifc4x3_add2::IfcAlignment(IfcParse::IfcGlobalId(), nullptr, alignment_name, boost::none, boost::none, placement, product_definition_shape, boost::none);
|
||||
auto alignment = new Ifc4x3_add2::IfcAlignment(IfcParse::IfcGlobalId(file.logger()), nullptr, alignment_name, boost::none, boost::none, placement, product_definition_shape, boost::none);
|
||||
file.addEntity(alignment);
|
||||
|
||||
|
||||
@@ -260,10 +260,10 @@ std::tuple<typename aggregate_of<Ifc4x3_add2::IfcObjectDefinition>::ptr, typenam
|
||||
{
|
||||
auto gradient_length = dxBG - length/2;
|
||||
auto design_parameters = new Ifc4x3_add2::IfcAlignmentVerticalSegment(boost::none, boost::none, xPBG, gradient_length, yPBG, start_slope, start_slope, boost::none, Ifc4x3_add2::IfcAlignmentVerticalSegmentTypeEnum::IfcAlignmentVerticalSegmentType_CONSTANTGRADIENT);
|
||||
auto alignment_segment = new Ifc4x3_add2::IfcAlignmentSegment(IfcParse::IfcGlobalId(), nullptr, boost::none, boost::none, boost::none, nullptr, nullptr, design_parameters);
|
||||
auto alignment_segment = new Ifc4x3_add2::IfcAlignmentSegment(IfcParse::IfcGlobalId(file.logger()), nullptr, boost::none, boost::none, boost::none, nullptr, nullptr, design_parameters);
|
||||
vertical_segments->push(alignment_segment);
|
||||
if (include_geometry) {
|
||||
vertical_curve_segments->push(mapAlignmentVerticalSegment(design_parameters).first);
|
||||
vertical_curve_segments->push(mapAlignmentVerticalSegment(design_parameters, file.logger()).first);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,10 +274,10 @@ std::tuple<typename aggregate_of<Ifc4x3_add2::IfcObjectDefinition>::ptr, typenam
|
||||
double yBVC = yPVI - start_slope * length / 2;
|
||||
|
||||
auto design_parameters = new Ifc4x3_add2::IfcAlignmentVerticalSegment(boost::none, boost::none, xBVC, length, yBVC, start_slope, end_slope, 1 / k, Ifc4x3_add2::IfcAlignmentVerticalSegmentTypeEnum::IfcAlignmentVerticalSegmentType_PARABOLICARC);
|
||||
auto alignment_segment = new Ifc4x3_add2::IfcAlignmentSegment(IfcParse::IfcGlobalId(), nullptr, boost::none, boost::none, boost::none, nullptr, nullptr, design_parameters);
|
||||
auto alignment_segment = new Ifc4x3_add2::IfcAlignmentSegment(IfcParse::IfcGlobalId(file.logger()), nullptr, boost::none, boost::none, boost::none, nullptr, nullptr, design_parameters);
|
||||
vertical_segments->push(alignment_segment);
|
||||
if (include_geometry) {
|
||||
vertical_curve_segments->push(mapAlignmentVerticalSegment(design_parameters).first);
|
||||
vertical_curve_segments->push(mapAlignmentVerticalSegment(design_parameters, file.logger()).first);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,18 +294,18 @@ std::tuple<typename aggregate_of<Ifc4x3_add2::IfcObjectDefinition>::ptr, typenam
|
||||
auto gradient_length = dx;
|
||||
|
||||
auto design_parameters = new Ifc4x3_add2::IfcAlignmentVerticalSegment(boost::none, boost::none, xPBG, gradient_length, yPBG, slope, slope, boost::none, Ifc4x3_add2::IfcAlignmentVerticalSegmentTypeEnum::IfcAlignmentVerticalSegmentType_CONSTANTGRADIENT);
|
||||
auto alignment_segment = new Ifc4x3_add2::IfcAlignmentSegment(IfcParse::IfcGlobalId(), nullptr, boost::none, boost::none, boost::none, nullptr, nullptr, design_parameters);
|
||||
auto alignment_segment = new Ifc4x3_add2::IfcAlignmentSegment(IfcParse::IfcGlobalId(file.logger()), nullptr, boost::none, boost::none, boost::none, nullptr, nullptr, design_parameters);
|
||||
vertical_segments->push(alignment_segment);
|
||||
if (include_geometry) {
|
||||
vertical_curve_segments->push(mapAlignmentVerticalSegment(design_parameters).first);
|
||||
vertical_curve_segments->push(mapAlignmentVerticalSegment(design_parameters, file.logger()).first);
|
||||
}
|
||||
|
||||
// create zero length terminator segment
|
||||
design_parameters = new Ifc4x3_add2::IfcAlignmentVerticalSegment(boost::none, boost::none, xPVI, 0.0, yPVI, slope, slope, boost::none, Ifc4x3_add2::IfcAlignmentVerticalSegmentTypeEnum::IfcAlignmentVerticalSegmentType_CONSTANTGRADIENT);
|
||||
alignment_segment = new Ifc4x3_add2::IfcAlignmentSegment(IfcParse::IfcGlobalId(), nullptr, boost::none, boost::none, boost::none, nullptr, nullptr, design_parameters);
|
||||
alignment_segment = new Ifc4x3_add2::IfcAlignmentSegment(IfcParse::IfcGlobalId(file.logger()), nullptr, boost::none, boost::none, boost::none, nullptr, nullptr, design_parameters);
|
||||
vertical_segments->push(alignment_segment);
|
||||
if (include_geometry) {
|
||||
auto segment = mapAlignmentVerticalSegment(design_parameters).first;
|
||||
auto segment = mapAlignmentVerticalSegment(design_parameters, file.logger()).first;
|
||||
segment->setTransition(Ifc4x3_add2::IfcTransitionCode::IfcTransitionCode_DISCONTINUOUS);
|
||||
vertical_curve_segments->push(segment);
|
||||
}
|
||||
@@ -329,19 +329,19 @@ Ifc4x3_add2::IfcAlignment* addAlignment(IfcHierarchyHelper<Ifc4x3_add2>& file, c
|
||||
//
|
||||
// Create the horizontal alignment (IfcAlignmentHorizontal) and nest the segments
|
||||
//
|
||||
auto horizontal_alignment = new Ifc4x3_add2::IfcAlignmentHorizontal(IfcParse::IfcGlobalId(), nullptr, alignment_name + std::string(" - Horizontal"), boost::none, boost::none, nullptr, nullptr);
|
||||
auto horizontal_alignment = new Ifc4x3_add2::IfcAlignmentHorizontal(IfcParse::IfcGlobalId(file.logger()), nullptr, alignment_name + std::string(" - Horizontal"), boost::none, boost::none, nullptr, nullptr);
|
||||
file.addEntity(horizontal_alignment);
|
||||
|
||||
auto nests_horizontal_segments = new Ifc4x3_add2::IfcRelNests(IfcParse::IfcGlobalId(), nullptr, boost::none, std::string("Nests horizontal alignment segments with horizontal alignment"), horizontal_alignment, horizontal_segments);
|
||||
auto nests_horizontal_segments = new Ifc4x3_add2::IfcRelNests(IfcParse::IfcGlobalId(file.logger()), nullptr, boost::none, std::string("Nests horizontal alignment segments with horizontal alignment"), horizontal_alignment, horizontal_segments);
|
||||
file.addEntity(nests_horizontal_segments);
|
||||
|
||||
//
|
||||
// Create the vertical alignment (IfcAlignmentVertical) and nest the segments
|
||||
//
|
||||
auto vertical_profile = new Ifc4x3_add2::IfcAlignmentVertical(IfcParse::IfcGlobalId(), nullptr, alignment_name + std::string("- Vertical"), boost::none, boost::none, nullptr, nullptr);
|
||||
auto vertical_profile = new Ifc4x3_add2::IfcAlignmentVertical(IfcParse::IfcGlobalId(file.logger()), nullptr, alignment_name + std::string("- Vertical"), boost::none, boost::none, nullptr, nullptr);
|
||||
file.addEntity(vertical_profile);
|
||||
|
||||
auto nests_vertical_segments = new Ifc4x3_add2::IfcRelNests(IfcParse::IfcGlobalId(), nullptr, boost::none, std::string("Nests vertical alignment segments with vertical alignment"), vertical_profile, vertical_segments);
|
||||
auto nests_vertical_segments = new Ifc4x3_add2::IfcRelNests(IfcParse::IfcGlobalId(file.logger()), nullptr, boost::none, std::string("Nests vertical alignment segments with vertical alignment"), vertical_profile, vertical_segments);
|
||||
file.addEntity(nests_vertical_segments);
|
||||
|
||||
Ifc4x3_add2::IfcLocalPlacement* placement = nullptr;
|
||||
@@ -383,7 +383,7 @@ Ifc4x3_add2::IfcAlignment* addAlignment(IfcHierarchyHelper<Ifc4x3_add2>& file, c
|
||||
// Create the IfcAlignment
|
||||
//
|
||||
|
||||
auto alignment = new Ifc4x3_add2::IfcAlignment(IfcParse::IfcGlobalId(), nullptr, alignment_name, boost::none, boost::none, placement, product_definition_shape, boost::none);
|
||||
auto alignment = new Ifc4x3_add2::IfcAlignment(IfcParse::IfcGlobalId(file.logger()), nullptr, alignment_name, boost::none, boost::none, placement, product_definition_shape, boost::none);
|
||||
file.addEntity(alignment);
|
||||
|
||||
// Nest the IfcAlignmentHorizontal and IfcAlignmentVertical with the IfcAlignment to complete the business logic
|
||||
@@ -393,31 +393,31 @@ Ifc4x3_add2::IfcAlignment* addAlignment(IfcHierarchyHelper<Ifc4x3_add2>& file, c
|
||||
alignment_layout_list->push(horizontal_alignment);
|
||||
alignment_layout_list->push(vertical_profile);
|
||||
|
||||
auto nests_alignment_layouts = new Ifc4x3_add2::IfcRelNests(IfcParse::IfcGlobalId(), nullptr, std::string("Nest horizontal and vertical alignment layouts with the alignment"), boost::none, alignment, alignment_layout_list);
|
||||
auto nests_alignment_layouts = new Ifc4x3_add2::IfcRelNests(IfcParse::IfcGlobalId(file.logger()), nullptr, std::string("Nest horizontal and vertical alignment layouts with the alignment"), boost::none, alignment, alignment_layout_list);
|
||||
file.addEntity(nests_alignment_layouts);
|
||||
|
||||
return alignment;
|
||||
}
|
||||
|
||||
std::pair<Ifc4x3_add2::IfcCurveSegment*, Ifc4x3_add2::IfcCurveSegment*> mapAlignmentSegment(const Ifc4x3_add2::IfcAlignmentSegment* segment) {
|
||||
std::pair<Ifc4x3_add2::IfcCurveSegment*, Ifc4x3_add2::IfcCurveSegment*> mapAlignmentSegment(const Ifc4x3_add2::IfcAlignmentSegment* segment, Logger& logger) {
|
||||
std::pair<Ifc4x3_add2::IfcCurveSegment*, Ifc4x3_add2::IfcCurveSegment*> result(nullptr, nullptr);
|
||||
auto design_parameters = segment->DesignParameters();
|
||||
auto horizontal = design_parameters->as<Ifc4x3_add2::IfcAlignmentHorizontalSegment>();
|
||||
auto vertical = design_parameters->as<Ifc4x3_add2::IfcAlignmentVerticalSegment>();
|
||||
auto cant = design_parameters->as<Ifc4x3_add2::IfcAlignmentCantSegment>();
|
||||
if (horizontal) {
|
||||
result = mapAlignmentHorizontalSegment(horizontal);
|
||||
result = mapAlignmentHorizontalSegment(horizontal, logger);
|
||||
} else if (vertical) {
|
||||
result = mapAlignmentVerticalSegment(vertical);
|
||||
result = mapAlignmentVerticalSegment(vertical, logger);
|
||||
} else if (cant) {
|
||||
result = mapAlignmentCantSegment(cant);
|
||||
result = mapAlignmentCantSegment(cant, logger);
|
||||
} else {
|
||||
Logger::Root().Error("VAL", 8, std::string("Unexpected IfcAlignmentSegment subtype encountered"));
|
||||
logger.Error("VAL", 8, std::string("Unexpected IfcAlignmentSegment subtype encountered"));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::pair<Ifc4x3_add2::IfcCurveSegment*, Ifc4x3_add2::IfcCurveSegment*> mapAlignmentHorizontalSegment(const Ifc4x3_add2::IfcAlignmentHorizontalSegment* segment) {
|
||||
std::pair<Ifc4x3_add2::IfcCurveSegment*, Ifc4x3_add2::IfcCurveSegment*> mapAlignmentHorizontalSegment(const Ifc4x3_add2::IfcAlignmentHorizontalSegment* segment, Logger& logger) {
|
||||
std::pair<Ifc4x3_add2::IfcCurveSegment*, Ifc4x3_add2::IfcCurveSegment*> result(nullptr, nullptr);
|
||||
auto start_point = segment->StartPoint();
|
||||
auto start_direction = segment->StartDirection();
|
||||
@@ -661,15 +661,15 @@ std::pair<Ifc4x3_add2::IfcCurveSegment*, Ifc4x3_add2::IfcCurveSegment*> mapAlign
|
||||
|
||||
result.first = curve_segment;
|
||||
} else if (type == Ifc4x3_add2::IfcAlignmentHorizontalSegmentTypeEnum::IfcAlignmentHorizontalSegmentType_VIENNESEBEND) {
|
||||
Logger::Root().Warning("UNS", 22, std::string("mapping of AlignmentHorizontalSegmentType VIENNESEBEND not supported"));
|
||||
logger.Warning("UNS", 22, std::string("mapping of AlignmentHorizontalSegmentType VIENNESEBEND not supported"));
|
||||
} else {
|
||||
Logger::Root().Error("VAL", 9, std::string("unexpected AlignmentHorizontalSegmentType encountered"));
|
||||
logger.Error("VAL", 9, std::string("unexpected AlignmentHorizontalSegmentType encountered"));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::pair<Ifc4x3_add2::IfcCurveSegment*, Ifc4x3_add2::IfcCurveSegment*> mapAlignmentVerticalSegment(const Ifc4x3_add2::IfcAlignmentVerticalSegment* segment) {
|
||||
std::pair<Ifc4x3_add2::IfcCurveSegment*, Ifc4x3_add2::IfcCurveSegment*> mapAlignmentVerticalSegment(const Ifc4x3_add2::IfcAlignmentVerticalSegment* segment, Logger& logger) {
|
||||
std::pair<Ifc4x3_add2::IfcCurveSegment*, Ifc4x3_add2::IfcCurveSegment*> result(nullptr, nullptr);
|
||||
auto start_distance_along = segment->StartDistAlong();
|
||||
auto horizontal_length = segment->HorizontalLength();
|
||||
@@ -732,7 +732,7 @@ std::pair<Ifc4x3_add2::IfcCurveSegment*, Ifc4x3_add2::IfcCurveSegment*> mapAlign
|
||||
|
||||
result.first = curve_segment;
|
||||
} else if (type == Ifc4x3_add2::IfcAlignmentVerticalSegmentTypeEnum::IfcAlignmentVerticalSegmentType_CLOTHOID) {
|
||||
Logger::Root().Warning("UNS", 23, std::string("mapping of AlignmentVerticalSegmentType CLOTHOID not supported"));
|
||||
logger.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,31 +760,31 @@ std::pair<Ifc4x3_add2::IfcCurveSegment*, Ifc4x3_add2::IfcCurveSegment*> mapAlign
|
||||
|
||||
result.first = curve_segment;
|
||||
} else {
|
||||
Logger::Root().Error("VAL", 10, std::string("unexpected AlignmentVerticalSegmentType encountered"));
|
||||
logger.Error("VAL", 10, std::string("unexpected AlignmentVerticalSegmentType encountered"));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::pair<Ifc4x3_add2::IfcCurveSegment*, Ifc4x3_add2::IfcCurveSegment*> mapAlignmentCantSegment(const Ifc4x3_add2::IfcAlignmentCantSegment* segment) {
|
||||
std::pair<Ifc4x3_add2::IfcCurveSegment*, Ifc4x3_add2::IfcCurveSegment*> mapAlignmentCantSegment(const Ifc4x3_add2::IfcAlignmentCantSegment* segment, Logger& logger) {
|
||||
std::pair<Ifc4x3_add2::IfcCurveSegment*, Ifc4x3_add2::IfcCurveSegment*> result(nullptr, nullptr);
|
||||
auto type = segment->PredefinedType();
|
||||
if (type == Ifc4x3_add2::IfcAlignmentCantSegmentTypeEnum::IfcAlignmentCantSegmentType_BLOSSCURVE) {
|
||||
Logger::Root().Warning("UNS", 24, std::string("mapping of AlignmentCantSegmentType BLOSSCURVE not supported"));
|
||||
logger.Warning("UNS", 24, std::string("mapping of AlignmentCantSegmentType BLOSSCURVE not supported"));
|
||||
} else if (type == Ifc4x3_add2::IfcAlignmentCantSegmentTypeEnum::IfcAlignmentCantSegmentType_CONSTANTCANT) {
|
||||
Logger::Root().Warning("UNS", 25, std::string("mapping of AlignmentCantSegmentType CONSTANTCANT not supported"));
|
||||
logger.Warning("UNS", 25, std::string("mapping of AlignmentCantSegmentType CONSTANTCANT not supported"));
|
||||
} else if (type == Ifc4x3_add2::IfcAlignmentCantSegmentTypeEnum::IfcAlignmentCantSegmentType_COSINECURVE) {
|
||||
Logger::Root().Warning("UNS", 26, std::string("mapping of AlignmentCantSegmentType COSINECURVE not supported"));
|
||||
logger.Warning("UNS", 26, std::string("mapping of AlignmentCantSegmentType COSINECURVE not supported"));
|
||||
} else if (type == Ifc4x3_add2::IfcAlignmentCantSegmentTypeEnum::IfcAlignmentCantSegmentType_HELMERTCURVE) {
|
||||
Logger::Root().Warning("UNS", 27, std::string("mapping of AlignmentCantSegmentType HELMERTCURVE not supported"));
|
||||
logger.Warning("UNS", 27, std::string("mapping of AlignmentCantSegmentType HELMERTCURVE not supported"));
|
||||
} else if (type == Ifc4x3_add2::IfcAlignmentCantSegmentTypeEnum::IfcAlignmentCantSegmentType_LINEARTRANSITION) {
|
||||
Logger::Root().Warning("UNS", 28, std::string("mapping of AlignmentCantSegmentType LINEARTRANSTION not supported"));
|
||||
logger.Warning("UNS", 28, std::string("mapping of AlignmentCantSegmentType LINEARTRANSTION not supported"));
|
||||
} else if (type == Ifc4x3_add2::IfcAlignmentCantSegmentTypeEnum::IfcAlignmentCantSegmentType_SINECURVE) {
|
||||
Logger::Root().Warning("UNS", 29, std::string("mapping of AlignmentCantSegmentType SINECURVE not supported"));
|
||||
logger.Warning("UNS", 29, std::string("mapping of AlignmentCantSegmentType SINECURVE not supported"));
|
||||
} else if (type == Ifc4x3_add2::IfcAlignmentCantSegmentTypeEnum::IfcAlignmentCantSegmentType_VIENNESEBEND) {
|
||||
Logger::Root().Warning("UNS", 30, std::string("mapping of AlignmentCantSegmentType VIENNESEBEND not supported"));
|
||||
logger.Warning("UNS", 30, std::string("mapping of AlignmentCantSegmentType VIENNESEBEND not supported"));
|
||||
} else {
|
||||
Logger::Root().Error("VAL", 11, std::string("unexpected AlignmentCantSegmentType encountered"));
|
||||
logger.Error("VAL", 11, std::string("unexpected AlignmentCantSegmentType encountered"));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -49,11 +49,11 @@ IFC_PARSE_API Ifc4x3_add2::IfcAlignment* addAlignment(IfcHierarchyHelper<Ifc4x3_
|
||||
// Maps horizontal alignment business logic to geometry.
|
||||
// Bloss curves have two geometry elements for one horizontal alignment segment. That is the reason for returning a pair.
|
||||
// Typically the first element of the pair will have the geometry and the second element will be nullptr
|
||||
IFC_PARSE_API std::pair<Ifc4x3_add2::IfcCurveSegment*, Ifc4x3_add2::IfcCurveSegment*> mapAlignmentSegment(const Ifc4x3_add2::IfcAlignmentSegment* segment);
|
||||
IFC_PARSE_API std::pair<Ifc4x3_add2::IfcCurveSegment*, Ifc4x3_add2::IfcCurveSegment*> mapAlignmentHorizontalSegment(const Ifc4x3_add2::IfcAlignmentHorizontalSegment* segment);
|
||||
IFC_PARSE_API std::pair<Ifc4x3_add2::IfcCurveSegment*, Ifc4x3_add2::IfcCurveSegment*> mapAlignmentVerticalSegment(const Ifc4x3_add2::IfcAlignmentVerticalSegment* segment);
|
||||
IFC_PARSE_API std::pair<Ifc4x3_add2::IfcCurveSegment*, Ifc4x3_add2::IfcCurveSegment*> mapAlignmentCantSegment(const Ifc4x3_add2::IfcAlignmentCantSegment* segment);
|
||||
IFC_PARSE_API std::pair<Ifc4x3_add2::IfcCurveSegment*, Ifc4x3_add2::IfcCurveSegment*> mapAlignmentSegment(const Ifc4x3_add2::IfcAlignmentSegment* segment, Logger& logger = Logger::Root());
|
||||
IFC_PARSE_API std::pair<Ifc4x3_add2::IfcCurveSegment*, Ifc4x3_add2::IfcCurveSegment*> mapAlignmentHorizontalSegment(const Ifc4x3_add2::IfcAlignmentHorizontalSegment* segment, Logger& logger = Logger::Root());
|
||||
IFC_PARSE_API std::pair<Ifc4x3_add2::IfcCurveSegment*, Ifc4x3_add2::IfcCurveSegment*> mapAlignmentVerticalSegment(const Ifc4x3_add2::IfcAlignmentVerticalSegment* segment, Logger& logger = Logger::Root());
|
||||
IFC_PARSE_API std::pair<Ifc4x3_add2::IfcCurveSegment*, Ifc4x3_add2::IfcCurveSegment*> mapAlignmentCantSegment(const Ifc4x3_add2::IfcAlignmentCantSegment* segment, Logger& logger = Logger::Root());
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -77,7 +77,9 @@
|
||||
|
||||
using namespace IfcParse;
|
||||
|
||||
IfcCharacterDecoder::IfcCharacterDecoder(IfcParse::FileReader* stream) {
|
||||
IfcCharacterDecoder::IfcCharacterDecoder(IfcParse::FileReader* stream, Logger& logger)
|
||||
: logger_(logger)
|
||||
{
|
||||
stream_ = stream;
|
||||
codepage_ = 0;
|
||||
}
|
||||
@@ -86,7 +88,7 @@ IfcCharacterDecoder::~IfcCharacterDecoder() {
|
||||
}
|
||||
|
||||
namespace {
|
||||
std::string read_string(IfcParse::FileReader& stream_, IfcParse::IfcCharacterDecoder::ConversionMode mode, char substitution_character) {
|
||||
std::string read_string(IfcParse::FileReader& stream_, Logger& logger, IfcParse::IfcCharacterDecoder::ConversionMode mode, char substitution_character) {
|
||||
std::u32string builder_;
|
||||
|
||||
unsigned int parse_state = 0;
|
||||
@@ -137,7 +139,7 @@ namespace {
|
||||
parse_state += PAGE;
|
||||
} else if (IS_HEXADECIMAL(current_char) && EXPECTS_HEX(parse_state)) {
|
||||
if (IS_LOWERCASE_HEX(current_char)) {
|
||||
Logger::Root().Warning("SYN", 2, "Lowercase hexadecimal character '" + std::string(1, current_char) +
|
||||
logger.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.");
|
||||
}
|
||||
@@ -211,13 +213,13 @@ namespace {
|
||||
} // namespace
|
||||
|
||||
IfcCharacterDecoder::operator std::string() {
|
||||
return read_string(*stream_, mode, substitution_character);
|
||||
return read_string(*stream_, logger_, mode, substitution_character);
|
||||
}
|
||||
|
||||
std::string IfcCharacterDecoder::get(size_t& ptr) {
|
||||
auto local_stream = *stream_;
|
||||
local_stream.seek(ptr);
|
||||
auto s = read_string(local_stream, mode, substitution_character);
|
||||
auto s = read_string(local_stream, logger_, mode, substitution_character);
|
||||
ptr = local_stream.tell();
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#define IFCCHARACTERDECODER_H
|
||||
|
||||
#include "FileReader.h"
|
||||
#include "IfcLogger.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
@@ -42,6 +43,7 @@ namespace IfcParse {
|
||||
class IFC_PARSE_API IfcCharacterDecoder {
|
||||
private:
|
||||
IfcParse::FileReader* stream_;
|
||||
Logger& logger_;
|
||||
int codepage_;
|
||||
|
||||
public:
|
||||
@@ -52,7 +54,7 @@ class IFC_PARSE_API IfcCharacterDecoder {
|
||||
};
|
||||
static ConversionMode mode;
|
||||
static char substitution_character;
|
||||
IfcCharacterDecoder(IfcParse::FileReader* stream);
|
||||
IfcCharacterDecoder(IfcParse::FileReader* stream, Logger& logger = Logger::Root());
|
||||
~IfcCharacterDecoder();
|
||||
// Only advances the underlying token stream read pointer
|
||||
// to the next token.
|
||||
|
||||
+23
-23
@@ -59,7 +59,7 @@ namespace {
|
||||
constexpr bool is_type_in_variant_v = is_type_in_variant<Variant, T>::value;
|
||||
|
||||
template <typename Fn>
|
||||
void dispatch_token(boost::optional<size_t> instance_id, int attribute_id, IfcParse::Token t, IfcParse::declaration* decl, Fn fn) {
|
||||
void dispatch_token(boost::optional<size_t> instance_id, int attribute_id, IfcParse::Token t, IfcParse::declaration* decl, Logger& logger, Fn fn) {
|
||||
if (t.type == IfcParse::Token_BINARY) {
|
||||
fn(IfcParse::TokenFunc::asBinary(t));
|
||||
} else if (IfcParse::TokenFunc::isBool(t)) {
|
||||
@@ -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::Root().Error("VAL", 12, "An enumeration literal '" + s + "' is not valid for type '" + decl->name() + "' at offset " + std::to_string(t.startPos));
|
||||
logger.Error("VAL", 12, "An enumeration literal '" + s + "' is not valid for type '" + decl->name() + "' at offset " + std::to_string(t.startPos));
|
||||
}
|
||||
} else {
|
||||
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));
|
||||
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));
|
||||
}
|
||||
} else if (t.type == IfcParse::Token_FLOAT) {
|
||||
fn(IfcParse::TokenFunc::asFloat(t));
|
||||
@@ -92,7 +92,7 @@ namespace {
|
||||
}
|
||||
|
||||
template <size_t Depth, typename Fn>
|
||||
void construct_(boost::optional<size_t> instance_id, int attribute_id, IfcParse::parse_context& p, const IfcParse::aggregation_type* aggr, Fn fn) {
|
||||
void construct_(boost::optional<size_t> instance_id, int attribute_id, IfcParse::parse_context& p, const IfcParse::aggregation_type* aggr, Logger& logger, Fn fn) {
|
||||
if (p.tokens_.empty()) {
|
||||
// @todo instead of ugly if-else we could also default initialize the respective
|
||||
// variant types below.
|
||||
@@ -135,7 +135,7 @@ namespace {
|
||||
|
||||
possible_aggregation_types_t aggregate_storage;
|
||||
|
||||
auto append_to_aggregate_storage = [&aggregate_storage](const auto& v) {
|
||||
auto append_to_aggregate_storage = [&aggregate_storage, &logger](const auto& v) {
|
||||
if constexpr (is_type_in_variant_v<possible_aggregation_types_t, std::vector<std::decay_t<decltype(v)>>>) {
|
||||
if (aggregate_storage.index() == 0) {
|
||||
aggregate_storage = std::vector<std::decay_t<decltype(v)>>{ v };
|
||||
@@ -194,7 +194,7 @@ namespace {
|
||||
}
|
||||
}, aggregate_storage);
|
||||
|
||||
Logger::Root().Error("VAL", 14, "Inconsistent aggregate valuation while attempting to append " + std::string(typeid(decltype(v)).name()) + " to an aggregate of " + current);
|
||||
logger.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,19 +213,19 @@ namespace {
|
||||
}
|
||||
} else {
|
||||
// @todo would be cool if we can trace this back to file offset
|
||||
Logger::Root().Error("UNS", 31, std::string("Aggregates of ") + typeid(decltype(v)).name() + " are not supported in the IfcOpenShell parser");
|
||||
logger.Error("UNS", 31, std::string("Aggregates of ") + typeid(decltype(v)).name() + " are not supported in the IfcOpenShell parser");
|
||||
}
|
||||
};
|
||||
|
||||
for (auto& t : p.tokens_) {
|
||||
std::visit([&aggregate_storage, &append_to_aggregate_storage, aggr, instance_id, attribute_id](const auto& v) {
|
||||
std::visit([&aggregate_storage, &append_to_aggregate_storage, aggr, instance_id, attribute_id, &logger](const auto& v) {
|
||||
if constexpr (std::is_same_v<std::decay_t<decltype(v)>, IfcParse::Token>) {
|
||||
// @todo get aggregate of enumeration
|
||||
dispatch_token(instance_id, attribute_id, v, aggr && aggr->type_of_element()->as_named_type() ? aggr->type_of_element()->as_named_type()->declared_type() : nullptr, append_to_aggregate_storage);
|
||||
dispatch_token(instance_id, attribute_id, v, aggr && aggr->type_of_element()->as_named_type() ? aggr->type_of_element()->as_named_type()->declared_type() : nullptr, logger, append_to_aggregate_storage);
|
||||
} else if constexpr (std::is_same_v<std::decay_t<decltype(v)>, IfcParse::parse_context*>) {
|
||||
// nested list
|
||||
if constexpr (Depth < 3) {
|
||||
construct_<Depth + 1>(instance_id, attribute_id, *v, nullptr, append_to_aggregate_storage);
|
||||
construct_<Depth + 1>(instance_id, attribute_id, *v, nullptr, logger, append_to_aggregate_storage);
|
||||
}
|
||||
} else {
|
||||
append_to_aggregate_storage(IfcParse::reference_or_simple_type{ v });
|
||||
@@ -237,7 +237,7 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
IfcEntityInstanceData IfcParse::parse_context::construct(boost::optional<size_t> name, unresolved_references& references_to_resolve, const IfcParse::declaration* decl, boost::optional<size_t> expected_size, int resolve_reference_index, bool coerce_attribute_count) {
|
||||
IfcEntityInstanceData IfcParse::parse_context::construct(boost::optional<size_t> name, unresolved_references& references_to_resolve, const IfcParse::declaration* decl, boost::optional<size_t> expected_size, int resolve_reference_index, Logger& logger, bool coerce_attribute_count) {
|
||||
std::vector<const IfcParse::parameter_type*> parameter_types;
|
||||
std::unique_ptr<IfcParse::named_type> transient_named_type;
|
||||
|
||||
@@ -263,9 +263,9 @@ IfcEntityInstanceData IfcParse::parse_context::construct(boost::optional<size_t>
|
||||
{
|
||||
size_t expected = expected_size ? *expected_size : parameter_types.size();
|
||||
if (decl != nullptr && decl->schema() == &Header_section_schema::get_schema()) {
|
||||
Logger::Root().Warning("VAL", 15, "Expected " + std::to_string(expected) + " attribute values, found " + std::to_string(tokens_.size()) + " for header entity " + decl->name());
|
||||
logger.Warning("VAL", 15, "Expected " + std::to_string(expected) + " attribute values, found " + std::to_string(tokens_.size()) + " for header entity " + decl->name());
|
||||
} else {
|
||||
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("")));
|
||||
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("")));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,9 +292,9 @@ IfcEntityInstanceData IfcParse::parse_context::construct(boost::optional<size_t>
|
||||
|
||||
auto index = (uint8_t) std::distance(tokens_.begin(), it);
|
||||
|
||||
std::visit([this, &storage, name, &references_to_resolve, index, param_type, resolve_reference_index](const auto& v) {
|
||||
std::visit([this, &storage, name, &references_to_resolve, index, param_type, resolve_reference_index, &logger](const auto& v) {
|
||||
if constexpr (std::is_same_v<std::decay_t<decltype(v)>, IfcParse::Token>) {
|
||||
dispatch_token(name, index, v, param_type && param_type->as_named_type() ? param_type->as_named_type()->declared_type() : nullptr, [this, &storage, name, &references_to_resolve, index, resolve_reference_index](auto v) {
|
||||
dispatch_token(name, index, v, param_type && param_type->as_named_type() ? param_type->as_named_type()->declared_type() : nullptr, logger, [this, &storage, name, &references_to_resolve, index, resolve_reference_index](auto v) {
|
||||
if constexpr (std::is_same_v<std::decay_t<decltype(v)>, IfcParse::reference_or_simple_type>) {
|
||||
if (name) {
|
||||
references_to_resolve.push_back(std::make_pair(
|
||||
@@ -316,7 +316,7 @@ IfcEntityInstanceData IfcParse::parse_context::construct(boost::optional<size_t>
|
||||
pt = pt->as_named_type()->declared_type()->as_type_declaration()->declared_type();
|
||||
}
|
||||
}
|
||||
construct_<0>(name, index, *v, pt ? pt->as_aggregation_type() : nullptr, [this, &storage, name, &references_to_resolve, index, resolve_reference_index](const auto& v) {
|
||||
construct_<0>(name, index, *v, pt ? pt->as_aggregation_type() : nullptr, logger, [this, &storage, name, &references_to_resolve, index, resolve_reference_index](const auto& v) {
|
||||
if constexpr (std::is_same_v<std::decay_t<decltype(v)>, std::vector<reference_or_simple_type>>) {
|
||||
if (name) {
|
||||
references_to_resolve.push_back({ { (uint32_t) *name, resolve_reference_index == -1 ? index : (uint8_t)resolve_reference_index }, v });
|
||||
@@ -719,13 +719,13 @@ std::optional<std::tuple<size_t, const IfcParse::declaration*, IfcEntityInstance
|
||||
try {
|
||||
entity_type = schema_->declaration_by_name(TokenFunc::asStringRef(token_stream_[2]));
|
||||
} catch (const IfcException& ex) {
|
||||
Logger::Root().Message(Logger::LOG_ERROR, "SYN", 3, std::string(ex.what()) + " at offset " + std::to_string(token_stream_[2].startPos));
|
||||
logger_.get().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::Root().Message(Logger::LOG_ERROR, "SYN", 4, "Non entity type " + entity_type->name() + " at offset " + std::to_string(token_stream_[2].startPos));
|
||||
logger_.get().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::optional<std::tuple<size_t, const IfcParse::declaration*, IfcEntityInstance
|
||||
storage_.load(current_id, entity_type->as_entity(), ps, -1);
|
||||
} catch (const IfcInvalidTokenException& e) {
|
||||
good_ = file_open_status::INVALID_SYNTAX;
|
||||
Logger::Root().Error("SYN", 5, e);
|
||||
logger_.get().Error("SYN", 5, e);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -753,10 +753,10 @@ std::optional<std::tuple<size_t, const IfcParse::declaration*, IfcEntityInstance
|
||||
if (((++progress_) % 1000) == 0) {
|
||||
std::stringstream ss;
|
||||
ss << "\r#" << current_id;
|
||||
Logger::Root().Status(ss.str(), false);
|
||||
logger_.get().Status(ss.str(), false);
|
||||
}
|
||||
|
||||
auto data = ps.construct(current_id, references_to_resolve_, entity_type, boost::none, -1, coerce_attribute_count);
|
||||
auto data = ps.construct(current_id, references_to_resolve_, entity_type, boost::none, -1, logger_.get(), coerce_attribute_count);
|
||||
|
||||
return_value.emplace(
|
||||
(size_t)current_id,
|
||||
@@ -769,9 +769,9 @@ std::optional<std::tuple<size_t, const IfcParse::declaration*, IfcEntityInstance
|
||||
try {
|
||||
next_token = lexer_->Next();
|
||||
} catch (const IfcException& e) {
|
||||
Logger::Root().Message(Logger::LOG_ERROR, "SYN", 6, std::string(e.what()) + ". Parsing terminated");
|
||||
logger_.get().Message(Logger::LOG_ERROR, "SYN", 6, std::string(e.what()) + ". Parsing terminated");
|
||||
} catch (...) {
|
||||
Logger::Root().Message(Logger::LOG_ERROR, "SYN", 7, "Parsing terminated");
|
||||
logger_.get().Message(Logger::LOG_ERROR, "SYN", 7, "Parsing terminated");
|
||||
}
|
||||
|
||||
if (!lexer_->stream->eof() && next_token.type == Token_NONE) {
|
||||
|
||||
+16
-12
@@ -27,6 +27,7 @@
|
||||
#include "storage.h"
|
||||
#include "file_open_status.h"
|
||||
|
||||
#include <functional>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/multi_index/random_access_index.hpp>
|
||||
#include <boost/multi_index/sequenced_index.hpp>
|
||||
@@ -96,6 +97,7 @@ private:
|
||||
const IfcParse::schema_definition* schema_;
|
||||
IfcParse::impl::in_memory_file_storage storage_;
|
||||
IfcParse::file_open_status good_ = IfcParse::file_open_status::SUCCESS;
|
||||
std::reference_wrapper<Logger> logger_;
|
||||
int progress_;
|
||||
IfcParse::unresolved_references references_to_resolve_;
|
||||
int yielded_header_instances_ = 0;
|
||||
@@ -144,13 +146,13 @@ private:
|
||||
|
||||
void pushPage(const std::string& page);
|
||||
|
||||
InstanceStreamer();
|
||||
InstanceStreamer(Logger& logger = Logger::Root());
|
||||
|
||||
InstanceStreamer(const std::string& fn, bool mmap=false);
|
||||
InstanceStreamer(const std::string& fn, bool mmap=false, Logger& logger = Logger::Root());
|
||||
|
||||
InstanceStreamer(void* data, int length);
|
||||
InstanceStreamer(void* data, int length, Logger& logger = Logger::Root());
|
||||
|
||||
InstanceStreamer(const IfcParse::schema_definition* schema, IfcParse::IfcSpfLexer* lexer);
|
||||
InstanceStreamer(const IfcParse::schema_definition* schema, IfcParse::IfcSpfLexer* lexer, Logger& logger = Logger::Root());
|
||||
|
||||
void bypassTypes(const std::set<std::string>& type_names);
|
||||
|
||||
@@ -199,6 +201,7 @@ public:
|
||||
|
||||
private:
|
||||
file_open_status good_ = file_open_status::SUCCESS;
|
||||
std::reference_wrapper<Logger> logger_;
|
||||
|
||||
const IfcParse::schema_definition* schema_;
|
||||
const IfcParse::declaration* ifcroot_type_;
|
||||
@@ -229,7 +232,7 @@ public:
|
||||
/// </summary>
|
||||
/// <param name="path">UTF-8 file path to an IFC-SPF file</param>
|
||||
/// <param name="mmap">Whether to use memory-mapped I/O</param>
|
||||
IfcFile(const std::string& path, bool mmap);
|
||||
IfcFile(const std::string& path, bool mmap, Logger& logger = Logger::Root());
|
||||
#endif
|
||||
/// <summary>
|
||||
/// Constructs an IfcFile object from a file path, supports IFC-SPF and the IfcOpenShell-specific RocksDB format.
|
||||
@@ -237,23 +240,23 @@ public:
|
||||
/// <param name="path">UTF-8 file path to an IFC-SPF file or RocksDB database directory</param>
|
||||
/// <param name="ty">File type of the path</param>
|
||||
/// <param name="readonly">Whether to open in read-only mode, only supported on RocksDB databases</param>
|
||||
IfcFile(const std::string& path, filetype ty=FT_AUTODETECT, bool readonly=false);
|
||||
IfcFile(const std::string& path, filetype ty=FT_AUTODETECT, bool readonly=false, Logger& logger = Logger::Root());
|
||||
|
||||
/// <summary>
|
||||
/// Constructs an IfcFile object from a stream containing IFC-SPF data.
|
||||
/// </summary>
|
||||
IfcFile(std::istream& stream, int length);
|
||||
IfcFile(std::istream& stream, int length, Logger& logger = Logger::Root());
|
||||
|
||||
/// <summary>
|
||||
/// Constructs an IfcFile object from a memory buffer containing IFC-SPF data.
|
||||
/// </summary>
|
||||
IfcFile(void* data, int length);
|
||||
IfcFile(void* data, int length, Logger& logger = Logger::Root());
|
||||
|
||||
/// <summary>
|
||||
/// Constructs an IfcFile object from a given IFC SPF stream.
|
||||
/// </summary>
|
||||
/// <param name="stream">A pointer to an IfcParse::FileReader object representing the input IFC SPF data stream.</param>
|
||||
IfcFile(IfcParse::FileReader* stream);
|
||||
IfcFile(IfcParse::FileReader* stream, Logger& logger = Logger::Root());
|
||||
|
||||
/// <summary>
|
||||
/// Constructs an IfcFile object with the specified schema, file type, and file path.
|
||||
@@ -262,12 +265,12 @@ public:
|
||||
/// <param name="schema">Pointer to the schema definition to use. Defaults to the IFC4 schema if not specified.</param>
|
||||
/// <param name="ty">The file type to use for the file. Defaults to FT_AUTODETECT.</param>
|
||||
/// <param name="path">The file system path to the IFC file. Defaults to an empty string.</param>
|
||||
IfcFile(const IfcParse::schema_definition* schema = IfcParse::schema_by_name("IFC4"), filetype ty = FT_AUTODETECT, const std::string& path = "");
|
||||
IfcFile(const IfcParse::schema_definition* schema = IfcParse::schema_by_name("IFC4"), filetype ty = FT_AUTODETECT, const std::string& path = "", Logger& logger = Logger::Root());
|
||||
|
||||
/// <summary>
|
||||
/// Constructs an unitialized IfcFile object. Call initialize() later on. Allows to specify which types to bypass during load.
|
||||
/// </summary>
|
||||
IfcFile(const uninitialized_tag&);
|
||||
IfcFile(const uninitialized_tag&, Logger& logger = Logger::Root());
|
||||
|
||||
bool initialize(const std::string& path, filetype ty = FT_AUTODETECT, bool readonly = false);
|
||||
#ifdef USE_MMAP
|
||||
@@ -281,6 +284,7 @@ public:
|
||||
~IfcFile();
|
||||
|
||||
IfcParse::file_open_status good() const { return good_; }
|
||||
Logger& logger() const { return logger_.get(); }
|
||||
|
||||
/// Returns the first entity in the range of instances contained in the model,
|
||||
/// in arbitrary order
|
||||
@@ -443,7 +447,7 @@ public:
|
||||
};
|
||||
|
||||
#ifdef WITH_IFCXML
|
||||
IFC_PARSE_API IfcFile* parse_ifcxml(const std::string& filename);
|
||||
IFC_PARSE_API IfcFile* parse_ifcxml(const std::string& filename, Logger& logger = Logger::Root());
|
||||
#endif
|
||||
|
||||
namespace impl {
|
||||
|
||||
@@ -94,7 +94,7 @@ void expand(const std::string& s, std::vector<unsigned char>& v) {
|
||||
static boost::uuids::basic_random_generator<boost::mt19937> gen;
|
||||
#endif
|
||||
|
||||
IfcParse::IfcGlobalId::IfcGlobalId() {
|
||||
IfcParse::IfcGlobalId::IfcGlobalId(Logger& logger) {
|
||||
uuid_data_ = gen();
|
||||
std::vector<unsigned char> v(uuid_data_.size());
|
||||
std::copy(uuid_data_.begin(), uuid_data_.end(), v.begin());
|
||||
@@ -111,12 +111,12 @@ 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::Root().Message(Logger::LOG_ERROR, "SYS", 34, "Internal error generating GlobalId");
|
||||
logger.Message(Logger::LOG_ERROR, "SYS", 34, "Internal error generating GlobalId");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
IfcParse::IfcGlobalId::IfcGlobalId(const std::string& string)
|
||||
IfcParse::IfcGlobalId::IfcGlobalId(const std::string& string, Logger& logger)
|
||||
: string_data_(string) {
|
||||
std::vector<unsigned char> result;
|
||||
expand(string_data_, result);
|
||||
@@ -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::Root().Message(Logger::LOG_ERROR, "SYS", 35, "Internal error generating GlobalId");
|
||||
logger.Message(Logger::LOG_ERROR, "SYS", 35, "Internal error generating GlobalId");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#define IFCGLOBALID_H
|
||||
|
||||
#include "ifc_parse_api.h"
|
||||
#include "IfcLogger.h"
|
||||
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
#include <string>
|
||||
@@ -36,8 +37,8 @@ class IFC_PARSE_API IfcGlobalId {
|
||||
|
||||
public:
|
||||
static const unsigned int length = 22;
|
||||
IfcGlobalId();
|
||||
IfcGlobalId(const std::string&);
|
||||
IfcGlobalId(Logger& logger = Logger::Root());
|
||||
IfcGlobalId(const std::string&, Logger& logger = Logger::Root());
|
||||
operator const std::string&() const;
|
||||
operator const boost::uuids::uuid&() const;
|
||||
const std::string& formatted() const;
|
||||
|
||||
@@ -129,7 +129,7 @@ typename Schema::IfcProject* IfcHierarchyHelper<Schema>::addProject(typename Sch
|
||||
|
||||
typename Schema::IfcUnitAssignment* unit_assignment = new typename Schema::IfcUnitAssignment(units);
|
||||
|
||||
typename Schema::IfcProject* project = new typename Schema::IfcProject(IfcParse::IfcGlobalId(),
|
||||
typename Schema::IfcProject* project = new typename Schema::IfcProject(IfcParse::IfcGlobalId(this->logger()),
|
||||
owner_hist,
|
||||
boost::none,
|
||||
boost::none,
|
||||
@@ -159,7 +159,7 @@ void IfcHierarchyHelper<Schema>::relatePlacements(typename Schema::IfcProduct* p
|
||||
if (local_place != parent->ObjectPlacement()) {
|
||||
local_place->setPlacementRelTo(parent->ObjectPlacement());
|
||||
} else {
|
||||
Logger::Root().Notice("SYN", 8, "Placement cannot be relative to self");
|
||||
this->logger().Notice("SYN", 8, "Placement cannot be relative to self");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -180,7 +180,7 @@ typename Schema::IfcSite* IfcHierarchyHelper<Schema>::addSite(typename Schema::I
|
||||
proj = addProject(owner_hist);
|
||||
}
|
||||
|
||||
typename Schema::IfcSite* site = new typename Schema::IfcSite(IfcParse::IfcGlobalId(),
|
||||
typename Schema::IfcSite* site = new typename Schema::IfcSite(IfcParse::IfcGlobalId(this->logger()),
|
||||
owner_hist,
|
||||
boost::none,
|
||||
boost::none,
|
||||
@@ -214,7 +214,7 @@ typename Schema::IfcBuilding* IfcHierarchyHelper<Schema>::addBuilding(typename S
|
||||
if (!site) {
|
||||
site = addSite(0, owner_hist);
|
||||
}
|
||||
typename Schema::IfcBuilding* building = new typename Schema::IfcBuilding(IfcParse::IfcGlobalId(),
|
||||
typename Schema::IfcBuilding* building = new typename Schema::IfcBuilding(IfcParse::IfcGlobalId(this->logger()),
|
||||
owner_hist,
|
||||
boost::none,
|
||||
boost::none,
|
||||
@@ -249,7 +249,7 @@ typename Schema::IfcBuildingStorey* IfcHierarchyHelper<Schema>::addBuildingStore
|
||||
if (!building) {
|
||||
building = addBuilding(0, owner_hist);
|
||||
}
|
||||
typename Schema::IfcBuildingStorey* storey = new typename Schema::IfcBuildingStorey(IfcParse::IfcGlobalId(),
|
||||
typename Schema::IfcBuildingStorey* storey = new typename Schema::IfcBuildingStorey(IfcParse::IfcGlobalId(this->logger()),
|
||||
owner_hist,
|
||||
boost::none,
|
||||
boost::none,
|
||||
|
||||
@@ -362,7 +362,7 @@ void set_children_of_relation(IfcUtil::IfcBaseClass* t, aggregate_of_instance::p
|
||||
template <typename Schema>
|
||||
class IFC_PARSE_API IfcHierarchyHelper : public IfcParse::IfcFile {
|
||||
public:
|
||||
IfcHierarchyHelper() : IfcParse::IfcFile(&Schema::get_schema()) {}
|
||||
IfcHierarchyHelper(Logger& logger = Logger::Root()) : IfcParse::IfcFile(&Schema::get_schema(), IfcParse::FT_AUTODETECT, "", logger) {}
|
||||
|
||||
template <class T>
|
||||
T* addTriplet(double x, double y, double z) {
|
||||
@@ -436,7 +436,7 @@ class IFC_PARSE_API IfcHierarchyHelper : public IfcParse::IfcFile {
|
||||
}
|
||||
typename Schema::IfcObject::list::ptr related_objects(new aggregate_of<typename Schema::IfcObject>());
|
||||
related_objects->push(related_object->template as<typename Schema::IfcObject>());
|
||||
typename Schema::IfcRelDefinesByType* t = new typename Schema::IfcRelDefinesByType(IfcParse::IfcGlobalId(), owner_hist, boost::none, boost::none, related_objects, relating_object->template as<typename Schema::IfcTypeObject>());
|
||||
typename Schema::IfcRelDefinesByType* t = new typename Schema::IfcRelDefinesByType(IfcParse::IfcGlobalId(this->logger()), owner_hist, boost::none, boost::none, related_objects, relating_object->template as<typename Schema::IfcTypeObject>());
|
||||
|
||||
addEntity(t);
|
||||
}
|
||||
@@ -454,9 +454,9 @@ class IFC_PARSE_API IfcHierarchyHelper : public IfcParse::IfcFile {
|
||||
break;
|
||||
}
|
||||
} catch (std::exception& e) {
|
||||
Logger::Root().Error("SYN", 9, e);
|
||||
this->logger().Error("SYN", 9, e);
|
||||
} catch (...) {
|
||||
Logger::Root().Error("SYN", 10, "Unknown error in addRelatedObject()");
|
||||
this->logger().Error("SYN", 10, "Unknown error in addRelatedObject()");
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
@@ -471,7 +471,7 @@ class IFC_PARSE_API IfcHierarchyHelper : public IfcParse::IfcFile {
|
||||
related_objects->push(related_object);
|
||||
|
||||
T* t = create(&T::Class())->template as<T>();
|
||||
t->set_attribute_value(0, (std::string)IfcParse::IfcGlobalId());
|
||||
t->set_attribute_value(0, (std::string)IfcParse::IfcGlobalId(this->logger()));
|
||||
t->set_attribute_value(1, owner_hist);
|
||||
int relating_index = 4;
|
||||
int related_index = 5;
|
||||
|
||||
+42
-10
@@ -32,8 +32,6 @@
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
static my_thread_local std::map<const Logger*, const IfcUtil::IfcBaseClass*> current_products_;
|
||||
|
||||
namespace {
|
||||
|
||||
std::string get_time(bool with_milliseconds = false) {
|
||||
@@ -139,16 +137,11 @@ Logger& Logger::Root() {
|
||||
}
|
||||
|
||||
const IfcUtil::IfcBaseClass* Logger::current_product() const {
|
||||
auto it = current_products_.find(this);
|
||||
return it == current_products_.end() ? nullptr : it->second;
|
||||
return current_product_;
|
||||
}
|
||||
|
||||
void Logger::current_product(const IfcUtil::IfcBaseClass* product) {
|
||||
if (product) {
|
||||
current_products_[this] = product;
|
||||
} else {
|
||||
current_products_.erase(this);
|
||||
}
|
||||
current_product_ = product;
|
||||
}
|
||||
|
||||
void Logger::SetProduct(boost::optional<const IfcUtil::IfcBaseClass*> product) {
|
||||
@@ -206,7 +199,7 @@ void Logger::Message(Logger::Severity type, const char (&code_prefix)[4], uint16
|
||||
}
|
||||
|
||||
if (format_ == FMT_INMEMORY) {
|
||||
log_messages_.emplace_back(type, code_prefix, code_number, message, instance);
|
||||
log_messages_.emplace_back(type, code_prefix, code_number, message, instance, current_product());
|
||||
} else if (((log2_ != nullptr) || (wlog2_ != nullptr))) {
|
||||
if (format_ == FMT_PLAIN) {
|
||||
if (log2_ != nullptr) {
|
||||
@@ -251,9 +244,48 @@ void Logger::ProgressBar(int progress) {
|
||||
}
|
||||
|
||||
std::string Logger::GetLog() {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
return log_stream_.str();
|
||||
}
|
||||
|
||||
void Logger::ClearLog() {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
log_stream_.str(std::string());
|
||||
log_stream_.clear();
|
||||
log_messages_.clear();
|
||||
}
|
||||
|
||||
void Logger::Append(Logger& logger) {
|
||||
if (&logger == this) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::scoped_lock lock(mutex_, logger.mutex_);
|
||||
|
||||
if (logger.max_severity_ > max_severity_) {
|
||||
max_severity_ = logger.max_severity_;
|
||||
}
|
||||
|
||||
if (format_ == FMT_INMEMORY) {
|
||||
log_messages_.insert(log_messages_.end(), logger.log_messages_.begin(), logger.log_messages_.end());
|
||||
} else {
|
||||
const std::string log = logger.log_stream_.str();
|
||||
if (!log.empty()) {
|
||||
if (log2_ != nullptr) {
|
||||
*log2_ << log;
|
||||
} else if (wlog2_ != nullptr) {
|
||||
*wlog2_ << string_as<wchar_t>(log);
|
||||
} else {
|
||||
log_stream_ << log;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger.log_stream_.str(std::string());
|
||||
logger.log_stream_.clear();
|
||||
logger.log_messages_.clear();
|
||||
}
|
||||
|
||||
void Logger::PrintPerformanceStats() {
|
||||
std::vector<std::pair<double, std::string>> items;
|
||||
for (auto& stat : performance_statistics_) {
|
||||
|
||||
@@ -31,14 +31,15 @@
|
||||
#include <mutex>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class IFC_PARSE_API log_message {
|
||||
public:
|
||||
char code[7];
|
||||
int severity;
|
||||
std::string message, instance;
|
||||
std::string message, instance, product;
|
||||
|
||||
log_message(int severity, const char (&code_prefix)[4], uint16_t code_number, const std::string& message, const IfcUtil::IfcBaseInterface* inst = 0)
|
||||
log_message(int severity, const char (&code_prefix)[4], uint16_t code_number, const std::string& message, const IfcUtil::IfcBaseInterface* inst = 0, const IfcUtil::IfcBaseClass* current_product = 0)
|
||||
: severity(severity)
|
||||
, message(message)
|
||||
{
|
||||
@@ -48,6 +49,11 @@ class IFC_PARSE_API log_message {
|
||||
inst->data().toString(nullptr, nullptr, 0, oss, true);
|
||||
instance = oss.str();
|
||||
}
|
||||
if (current_product) {
|
||||
std::ostringstream oss;
|
||||
current_product->toString(oss);
|
||||
product = oss.str();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -79,6 +85,7 @@ class IFC_PARSE_API Logger {
|
||||
std::wostream* wlog2_ = nullptr;
|
||||
|
||||
std::stringstream log_stream_;
|
||||
const IfcUtil::IfcBaseClass* current_product_ = nullptr;
|
||||
|
||||
Severity verbosity_ = LOG_NOTICE;
|
||||
Format format_ = FMT_PLAIN;
|
||||
@@ -134,8 +141,11 @@ class IFC_PARSE_API Logger {
|
||||
|
||||
void ProgressBar(int progress);
|
||||
std::string GetLog();
|
||||
void ClearLog();
|
||||
void Append(Logger& logger);
|
||||
void PrintPerformanceStats();
|
||||
void PrintPerformanceStatsOnElement(bool b) { print_perf_stats_on_element_ = b; }
|
||||
bool PrintPerformanceStatsOnElement() const { return print_perf_stats_on_element_; }
|
||||
|
||||
const std::vector<log_message>& log_messages() const { return log_messages_; }
|
||||
};
|
||||
|
||||
+94
-63
@@ -102,9 +102,11 @@ void init_locale() {
|
||||
|
||||
#endif
|
||||
|
||||
IfcSpfLexer::IfcSpfLexer(IfcParse::FileReader* stream_) {
|
||||
IfcSpfLexer::IfcSpfLexer(IfcParse::FileReader* stream_, Logger& logger)
|
||||
: logger_(logger)
|
||||
{
|
||||
stream = stream_;
|
||||
decoder_ = new IfcCharacterDecoder(stream_);
|
||||
decoder_ = new IfcCharacterDecoder(stream_, logger_);
|
||||
}
|
||||
|
||||
IfcSpfLexer::~IfcSpfLexer() {
|
||||
@@ -320,7 +322,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::Root().Message(Logger::LOG_ERROR, "SYN", 11, "Token '" + tokenStr + "' at offset " + std::to_string(token.startPos) + " is not valid");
|
||||
lexer->logger().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 = '$';
|
||||
}
|
||||
@@ -562,13 +564,13 @@ void IfcParse::impl::in_memory_file_storage::load(boost::optional<size_t> entity
|
||||
// type) and to be able to actually register the references in
|
||||
// the 2nd pass.
|
||||
load(entity_instance_name, entity, ps, attribute_index == -1 ? (int)attribute_index_within_data : attribute_index);
|
||||
auto* simple_type_instance = (schema ? schema : file->schema())->instantiate(decl, ps.construct(entity_instance_name, *references_to_resolve, decl, boost::none, attribute_index == -1 ? (int)attribute_index_within_data : attribute_index));
|
||||
auto* simple_type_instance = (schema ? schema : file->schema())->instantiate(decl, ps.construct(entity_instance_name, *references_to_resolve, decl, boost::none, attribute_index == -1 ? (int)attribute_index_within_data : attribute_index, logger()));
|
||||
read_simple_type_instances.emplace_back(simple_type_instance);
|
||||
//@todo decide addEntity(((IfcUtil::IfcBaseClass*)*entity));
|
||||
context.push(simple_type_instance);
|
||||
simple_type_instance->file_ = file;
|
||||
} catch (IfcException& e) {
|
||||
Logger::Root().Message(Logger::LOG_ERROR, "SYN", 12, std::string(e.what()) + " at offset " + std::to_string(next.startPos));
|
||||
logger().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--;
|
||||
}
|
||||
@@ -592,7 +594,7 @@ IfcEntityInstanceData IfcParse::impl::in_memory_file_storage::read(unsigned int
|
||||
parse_context pc;
|
||||
tokens->Next();
|
||||
load(i, ty->as_entity(), pc, -1);
|
||||
return IfcEntityInstanceData(pc.construct(i, *references_to_resolve, ty, boost::none, -1));
|
||||
return IfcEntityInstanceData(pc.construct(i, *references_to_resolve, ty, boost::none, -1, logger()));
|
||||
}
|
||||
|
||||
void IfcParse::impl::in_memory_file_storage::try_read_semicolon() const {
|
||||
@@ -663,7 +665,7 @@ void IfcParse::impl::rocks_db_file_storage::unregister_inverse(unsigned id_from,
|
||||
if (it != vals.end()) {
|
||||
vals.erase(it);
|
||||
} else {
|
||||
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));
|
||||
file->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));
|
||||
}
|
||||
s.resize(vals.size() * sizeof(uint32_t));
|
||||
memcpy(s.data(), vals.data(), s.size());
|
||||
@@ -1122,7 +1124,7 @@ IfcUtil::IfcBaseClass::set_attribute_value(size_t i, const T& t) {
|
||||
}
|
||||
}
|
||||
} catch (IfcParse::IfcException& e) {
|
||||
Logger::Root().Error("SYN", 13, e);
|
||||
file_->logger().Error("SYN", 13, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1159,11 +1161,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::Root().Warning("VAL", 18, "Duplicate guid " + guid);
|
||||
file_->logger().Warning("VAL", 18, "Duplicate guid " + guid);
|
||||
}
|
||||
file_->internal_guid_map().insert({ guid, this });
|
||||
} catch (IfcParse::IfcException& e) {
|
||||
Logger::Root().Error("SYN", 14, e);
|
||||
file_->logger().Error("SYN", 14, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1182,7 +1184,13 @@ IfcUtil::IfcBaseClass::set_attribute_value(const std::string& s, const T& t) {
|
||||
// Creates the maps
|
||||
//
|
||||
#ifdef USE_MMAP
|
||||
IfcFile::IfcFile(const std::string& fn, bool mmap) {
|
||||
IfcFile::IfcFile(const std::string& fn, bool mmap, Logger& logger)
|
||||
: logger_(logger)
|
||||
, schema_(nullptr)
|
||||
, ifcroot_type_(nullptr)
|
||||
, max_id_(0)
|
||||
, _header(this, logger)
|
||||
{
|
||||
initialize(fn, mmap);
|
||||
}
|
||||
|
||||
@@ -1194,7 +1202,7 @@ bool IfcParse::IfcFile::initialize(const std::string& fn, bool mmap) {
|
||||
s = std::make_unique<FileReader>(fn);
|
||||
}
|
||||
|
||||
storage_.emplace<1>(this);
|
||||
storage_.emplace<1>(this, logger_.get());
|
||||
std::get<impl::in_memory_file_storage>(storage_).read_from_stream(&*s, schema_, max_id_, types_to_bypass_loading_);
|
||||
|
||||
if ((good_ = std::get<impl::in_memory_file_storage>(storage_).good_)) {
|
||||
@@ -1209,8 +1217,8 @@ bool IfcParse::IfcFile::initialize(const std::string& fn, bool mmap) {
|
||||
}
|
||||
#endif
|
||||
|
||||
IfcFile::IfcFile(const uninitialized_tag&)
|
||||
: schema_(nullptr), max_id_(0), _header(this), good_(file_open_status::UNKNOWN), ifcroot_type_(nullptr) {}
|
||||
IfcFile::IfcFile(const uninitialized_tag&, Logger& logger)
|
||||
: logger_(logger), schema_(nullptr), ifcroot_type_(nullptr), max_id_(0), _header(this, logger), good_(file_open_status::UNKNOWN) {}
|
||||
|
||||
bool IfcParse::IfcFile::initialize(const std::string& path, filetype ty, bool readonly) {
|
||||
if (ty == FT_AUTODETECT) {
|
||||
@@ -1218,7 +1226,7 @@ bool IfcParse::IfcFile::initialize(const std::string& path, filetype ty, bool re
|
||||
}
|
||||
if (ty == FT_IFCSPF) {
|
||||
FileReader s(path);
|
||||
storage_.emplace<1>(this);
|
||||
storage_.emplace<1>(this, logger_.get());
|
||||
std::get<impl::in_memory_file_storage>(storage_).read_from_stream(&s, schema_, max_id_, types_to_bypass_loading_);
|
||||
|
||||
if ((good_ = std::get<impl::in_memory_file_storage>(storage_).good_)) {
|
||||
@@ -1261,17 +1269,22 @@ void IfcParse::IfcFile::bypass_type(const std::string& type_name) {
|
||||
types_to_bypass_loading_.insert(type_name);
|
||||
}
|
||||
|
||||
IfcFile::IfcFile(const std::string& path, filetype ty, bool readonly)
|
||||
: schema_(nullptr)
|
||||
IfcFile::IfcFile(const std::string& path, filetype ty, bool readonly, Logger& logger)
|
||||
: logger_(logger)
|
||||
, schema_(nullptr)
|
||||
, ifcroot_type_(nullptr)
|
||||
, max_id_(0)
|
||||
, _header(this)
|
||||
, _header(this, logger)
|
||||
{
|
||||
initialize(path, ty, readonly);
|
||||
}
|
||||
|
||||
IfcFile::IfcFile(std::istream& stream, int length)
|
||||
: schema_(nullptr)
|
||||
IfcFile::IfcFile(std::istream& stream, int length, Logger& logger)
|
||||
: logger_(logger)
|
||||
, schema_(nullptr)
|
||||
, ifcroot_type_(nullptr)
|
||||
, max_id_(0)
|
||||
, _header(this, logger)
|
||||
{
|
||||
FileReader s(FileReader::caller_fed_tag{});
|
||||
|
||||
@@ -1280,7 +1293,7 @@ IfcFile::IfcFile(std::istream& stream, int length)
|
||||
stream.read(string_data.data(), length);
|
||||
s.pushNextPage(string_data);
|
||||
|
||||
storage_.emplace<1>(this);
|
||||
storage_.emplace<1>(this, logger_.get());
|
||||
std::get<impl::in_memory_file_storage>(storage_).read_from_stream(&s, schema_, max_id_, types_to_bypass_loading_);
|
||||
good_ = std::get<impl::in_memory_file_storage>(storage_).good_;
|
||||
ifcroot_type_ = schema_ ? schema_->declaration_by_name("IfcRoot") : nullptr;
|
||||
@@ -1290,13 +1303,16 @@ IfcFile::IfcFile(std::istream& stream, int length)
|
||||
byguid_ = decltype(byguid_)(&std::get<impl::in_memory_file_storage>(storage_).byguid_);
|
||||
}
|
||||
|
||||
IfcFile::IfcFile(void* data, int length)
|
||||
: schema_(nullptr)
|
||||
IfcFile::IfcFile(void* data, int length, Logger& logger)
|
||||
: logger_(logger)
|
||||
, schema_(nullptr)
|
||||
, ifcroot_type_(nullptr)
|
||||
, max_id_(0)
|
||||
, _header(this, logger)
|
||||
{
|
||||
FileReader s(std::string((char*)data, length), FileReader::caller_fed_tag{});
|
||||
|
||||
storage_.emplace<1>(this);
|
||||
storage_.emplace<1>(this, logger_.get());
|
||||
std::get<impl::in_memory_file_storage>(storage_).read_from_stream(&s, schema_, max_id_, types_to_bypass_loading_);
|
||||
good_ = std::get<impl::in_memory_file_storage>(storage_).good_;
|
||||
ifcroot_type_ = schema_ ? schema_->declaration_by_name("IfcRoot") : nullptr;
|
||||
@@ -1306,11 +1322,14 @@ IfcFile::IfcFile(void* data, int length)
|
||||
byguid_ = decltype(byguid_)(&std::get<impl::in_memory_file_storage>(storage_).byguid_);
|
||||
}
|
||||
|
||||
IfcFile::IfcFile(IfcParse::FileReader* s)
|
||||
: schema_(nullptr)
|
||||
IfcFile::IfcFile(IfcParse::FileReader* s, Logger& logger)
|
||||
: logger_(logger)
|
||||
, schema_(nullptr)
|
||||
, ifcroot_type_(nullptr)
|
||||
, max_id_(0)
|
||||
, _header(this, logger)
|
||||
{
|
||||
storage_.emplace<1>(this);
|
||||
storage_.emplace<1>(this, logger_.get());
|
||||
std::get<impl::in_memory_file_storage>(storage_).read_from_stream(s, schema_, max_id_, types_to_bypass_loading_);
|
||||
good_ = std::get<impl::in_memory_file_storage>(storage_).good_;
|
||||
ifcroot_type_ = schema_ ? schema_->declaration_by_name("IfcRoot") : nullptr;
|
||||
@@ -1320,16 +1339,18 @@ IfcFile::IfcFile(IfcParse::FileReader* s)
|
||||
byguid_ = decltype(byguid_)(&std::get<impl::in_memory_file_storage>(storage_).byguid_);
|
||||
}
|
||||
|
||||
IfcFile::IfcFile(const IfcParse::schema_definition* schema, filetype ty, const std::string& path)
|
||||
: schema_(schema)
|
||||
IfcFile::IfcFile(const IfcParse::schema_definition* schema, filetype ty, const std::string& path, Logger& logger)
|
||||
: logger_(logger)
|
||||
, schema_(schema)
|
||||
, ifcroot_type_(schema_->declaration_by_name("IfcRoot"))
|
||||
, max_id_(0)
|
||||
, _header(this, logger)
|
||||
{
|
||||
if (ty == FT_AUTODETECT) {
|
||||
ty = guess_file_type(path);
|
||||
}
|
||||
if (ty == FT_IFCSPF) {
|
||||
storage_.emplace<1>(this);
|
||||
storage_.emplace<1>(this, logger_.get());
|
||||
|
||||
byid_ = decltype(byid_)(&std::get<impl::in_memory_file_storage>(storage_).byid_);
|
||||
byref_excl_ = decltype(byref_excl_)(&std::get<impl::in_memory_file_storage>(storage_).byref_excl_);
|
||||
@@ -1347,13 +1368,12 @@ IfcFile::IfcFile(const IfcParse::schema_definition* schema, filetype ty, const s
|
||||
} else {
|
||||
throw std::runtime_error("Unsupported file format");
|
||||
}
|
||||
_header = IfcSpfHeader(this);
|
||||
setDefaultHeaderValues();
|
||||
}
|
||||
|
||||
bool IfcParse::InstanceStreamer::hasSemicolon() const {
|
||||
auto local_stream = stream_->clone();
|
||||
auto local_lexer = IfcSpfLexer(&local_stream);
|
||||
auto local_lexer = IfcSpfLexer(&local_stream, logger_.get());
|
||||
Token t;
|
||||
try {
|
||||
t = local_lexer.Next();
|
||||
@@ -1376,7 +1396,7 @@ bool IfcParse::InstanceStreamer::hasSemicolon() const {
|
||||
|
||||
size_t IfcParse::InstanceStreamer::semicolonCount() const {
|
||||
auto local_stream = stream_->clone();
|
||||
auto local_lexer = IfcSpfLexer(&local_stream);
|
||||
auto local_lexer = IfcSpfLexer(&local_stream, logger_.get());
|
||||
Token t;
|
||||
size_t count = 0;
|
||||
try {
|
||||
@@ -1402,7 +1422,7 @@ void IfcParse::InstanceStreamer::pushPage(const std::string& page)
|
||||
{
|
||||
stream_->pushNextPage(page);
|
||||
if (good_ == file_open_status::NO_HEADER) {
|
||||
header_ = new IfcParse::IfcSpfHeader(lexer_);
|
||||
header_ = new IfcParse::IfcSpfHeader(lexer_, logger_.get());
|
||||
if (header_->tryRead() && header_->file_schema()->schema_identifiers().size() == 1) {
|
||||
try {
|
||||
schema_ = IfcParse::schema_by_name(header_->file_schema()->schema_identifiers().front());
|
||||
@@ -1417,29 +1437,35 @@ void IfcParse::InstanceStreamer::pushPage(const std::string& page)
|
||||
}
|
||||
}
|
||||
|
||||
IfcParse::InstanceStreamer::InstanceStreamer()
|
||||
IfcParse::InstanceStreamer::InstanceStreamer(Logger& logger)
|
||||
: stream_(new FileReader(FileReader::caller_fed_tag{}))
|
||||
, lexer_(new IfcSpfLexer(stream_))
|
||||
, lexer_(new IfcSpfLexer(stream_, logger))
|
||||
, header_(nullptr)
|
||||
, token_stream_(3, Token{})
|
||||
, schema_(nullptr)
|
||||
, storage_(nullptr, logger)
|
||||
, logger_(logger)
|
||||
, progress_(0)
|
||||
{
|
||||
init_locale();
|
||||
good_ = file_open_status::NO_HEADER;
|
||||
}
|
||||
|
||||
IfcParse::InstanceStreamer::InstanceStreamer(const std::string& fn, bool mmap)
|
||||
IfcParse::InstanceStreamer::InstanceStreamer(const std::string& fn, bool mmap, Logger& logger)
|
||||
: stream_(mmap ? new FileReader(fn, FileReader::mmap_tag{}) : new FileReader(fn))
|
||||
, lexer_(new IfcSpfLexer(stream_))
|
||||
, lexer_(new IfcSpfLexer(stream_, logger))
|
||||
, header_(nullptr)
|
||||
, token_stream_(3, Token{})
|
||||
, schema_(nullptr)
|
||||
, storage_(nullptr, logger)
|
||||
, logger_(logger)
|
||||
, progress_(0)
|
||||
{
|
||||
init_locale();
|
||||
|
||||
good_ = file_open_status::NO_HEADER;
|
||||
if (stream_->size() && !stream_->eof()) {
|
||||
header_ = new IfcParse::IfcSpfHeader(lexer_);
|
||||
header_ = new IfcParse::IfcSpfHeader(lexer_, logger_.get());
|
||||
if (header_->tryRead() && header_->file_schema()->schema_identifiers().size() == 1) {
|
||||
try {
|
||||
schema_ = IfcParse::schema_by_name(header_->file_schema()->schema_identifiers().front());
|
||||
@@ -1454,18 +1480,21 @@ IfcParse::InstanceStreamer::InstanceStreamer(const std::string& fn, bool mmap)
|
||||
}
|
||||
}
|
||||
|
||||
IfcParse::InstanceStreamer::InstanceStreamer(void* data, int length)
|
||||
IfcParse::InstanceStreamer::InstanceStreamer(void* data, int length, Logger& logger)
|
||||
: stream_(new FileReader(std::string((char*) data, length), FileReader::caller_fed_tag{}))
|
||||
, lexer_(new IfcSpfLexer(stream_))
|
||||
, lexer_(new IfcSpfLexer(stream_, logger))
|
||||
, header_(nullptr)
|
||||
, token_stream_(3, Token{})
|
||||
, schema_(nullptr)
|
||||
, storage_(nullptr, logger)
|
||||
, logger_(logger)
|
||||
, progress_(0)
|
||||
{
|
||||
init_locale();
|
||||
|
||||
good_ = file_open_status::NO_HEADER;
|
||||
if (stream_->size() && !stream_->eof()) {
|
||||
header_ = new IfcParse::IfcSpfHeader(lexer_);
|
||||
header_ = new IfcParse::IfcSpfHeader(lexer_, logger_.get());
|
||||
if (header_->tryRead() && header_->file_schema()->schema_identifiers().size() == 1) {
|
||||
try {
|
||||
schema_ = IfcParse::schema_by_name(header_->file_schema()->schema_identifiers().front());
|
||||
@@ -1480,12 +1509,14 @@ IfcParse::InstanceStreamer::InstanceStreamer(void* data, int length)
|
||||
}
|
||||
}
|
||||
|
||||
IfcParse::InstanceStreamer::InstanceStreamer(const IfcParse::schema_definition* schema, IfcParse::IfcSpfLexer* lexer)
|
||||
IfcParse::InstanceStreamer::InstanceStreamer(const IfcParse::schema_definition* schema, IfcParse::IfcSpfLexer* lexer, Logger& logger)
|
||||
: stream_(nullptr)
|
||||
, lexer_(lexer)
|
||||
, header_(nullptr)
|
||||
, token_stream_(3, Token{})
|
||||
, schema_(schema)
|
||||
, storage_(nullptr, logger)
|
||||
, logger_(logger)
|
||||
, progress_(0)
|
||||
{
|
||||
init_locale();
|
||||
@@ -1509,7 +1540,7 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(IfcParse::FileRead
|
||||
return;
|
||||
}
|
||||
|
||||
tokens = new IfcSpfLexer(s);
|
||||
tokens = new IfcSpfLexer(s, logger());
|
||||
|
||||
std::vector<std::string> schemas;
|
||||
|
||||
@@ -1531,21 +1562,21 @@ 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::Root().Error("SYN", 15, e);
|
||||
logger().Error("SYN", 15, e);
|
||||
}
|
||||
}
|
||||
|
||||
if (schema == nullptr) {
|
||||
Logger::Root().Message(Logger::LOG_ERROR, "UNS", 32, "No support for file schema encountered (" + boost::algorithm::join(schemas, ", ") + ")");
|
||||
logger().Message(Logger::LOG_ERROR, "UNS", 32, "No support for file schema encountered (" + boost::algorithm::join(schemas, ", ") + ")");
|
||||
return;
|
||||
}
|
||||
|
||||
auto ifcroot_type_ = schema->declaration_by_name("IfcRoot");
|
||||
|
||||
InstanceStreamer streamer(schema, tokens);
|
||||
InstanceStreamer streamer(schema, tokens, logger());
|
||||
streamer.bypassTypes(typed_to_bypass);
|
||||
|
||||
Logger::Root().Status("Scanning file...");
|
||||
logger().Status("Scanning file...");
|
||||
|
||||
while (streamer) {
|
||||
|
||||
@@ -1569,11 +1600,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::Root().Message(Logger::LOG_WARNING, "SYN", 16, ss.str());
|
||||
logger().Message(Logger::LOG_WARNING, "SYN", 16, ss.str());
|
||||
}
|
||||
byguid_[guid] = instance;
|
||||
} catch (const IfcException& ex) {
|
||||
Logger::Root().Message(Logger::LOG_ERROR, "SYN", 17, ex.what());
|
||||
logger().Message(Logger::LOG_ERROR, "SYN", 17, ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1589,7 +1620,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::Root().Message(Logger::LOG_WARNING, "SYN", 18, ss.str());
|
||||
logger().Message(Logger::LOG_WARNING, "SYN", 18, ss.str());
|
||||
}
|
||||
|
||||
// byidentity_[instance->identity()] = instance;
|
||||
@@ -1612,7 +1643,7 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(IfcParse::FileRead
|
||||
inst->file_ = file;
|
||||
}
|
||||
|
||||
Logger::Root().Status("\rDone scanning file ");
|
||||
logger().Status("\rDone scanning file ");
|
||||
|
||||
delete tokens;
|
||||
|
||||
@@ -1632,7 +1663,7 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(IfcParse::FileRead
|
||||
}
|
||||
auto it = byid_.find(*name);
|
||||
if (it == byid_.end()) {
|
||||
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));
|
||||
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));
|
||||
} else {
|
||||
auto* storage = &byid_[p.first.name_]->data();
|
||||
auto attr_index = p.first.index_;
|
||||
@@ -1649,7 +1680,7 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(IfcParse::FileRead
|
||||
if (storage->has_attribute_value<Blank>(nullptr, nullptr, 0, attr_index)) {
|
||||
storage->set_attribute_value(nullptr, nullptr, 0, attr_index, it->second);
|
||||
} else {
|
||||
Logger::Root().Error("SYN", 20, "Duplicate definition for instance reference");
|
||||
logger().Error("SYN", 20, "Duplicate definition for instance reference");
|
||||
}
|
||||
}
|
||||
} else if (auto* inst = std::get_if<IfcUtil::IfcBaseClass*>(v)) {
|
||||
@@ -1665,7 +1696,7 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(IfcParse::FileRead
|
||||
}
|
||||
auto it = byid_.find(*name);
|
||||
if (it == byid_.end()) {
|
||||
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));
|
||||
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));
|
||||
} else {
|
||||
instances->push(it->second);
|
||||
}
|
||||
@@ -1689,7 +1720,7 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(IfcParse::FileRead
|
||||
if (storage->has_attribute_value<Blank>(nullptr, nullptr, 0, attr_index)) {
|
||||
storage->set_attribute_value(nullptr, nullptr, 0, attr_index, instances);
|
||||
} else {
|
||||
Logger::Root().Error("SYN", 22, "Duplicate definition for instance reference");
|
||||
logger().Error("SYN", 22, "Duplicate definition for instance reference");
|
||||
}
|
||||
} else if (auto* vvv = std::get_if<std::vector<std::vector<reference_or_simple_type>>>(&p.second)) {
|
||||
aggregate_of_aggregate_of_instance::ptr instances(new aggregate_of_aggregate_of_instance);
|
||||
@@ -1702,7 +1733,7 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(IfcParse::FileRead
|
||||
}
|
||||
auto it = byid_.find(*name);
|
||||
if (it == byid_.end()) {
|
||||
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));
|
||||
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));
|
||||
} else {
|
||||
inner.push_back(it->second);
|
||||
}
|
||||
@@ -1728,12 +1759,12 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(IfcParse::FileRead
|
||||
if (storage->has_attribute_value<Blank>(nullptr, nullptr, 0, attr_index)) {
|
||||
storage->set_attribute_value(nullptr, nullptr, 0, attr_index, instances);
|
||||
} else {
|
||||
Logger::Root().Error("SYN", 24, "Duplicate definition for instance reference");
|
||||
logger().Error("SYN", 24, "Duplicate definition for instance reference");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Logger::Root().Status("Done resolving references");
|
||||
logger().Status("Done resolving references");
|
||||
}
|
||||
|
||||
void IfcFile::recalculate_id_counter() {
|
||||
@@ -1893,7 +1924,7 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity, int id)
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
Logger::Root().Message(Logger::LOG_ERROR, "SYN", 25, "Failed to visit forward references of", entity);
|
||||
logger().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 +2097,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::Root().Message(Logger::LOG_WARNING, "SYN", 26, ss.str());
|
||||
logger().Message(Logger::LOG_WARNING, "SYN", 26, ss.str());
|
||||
}
|
||||
byguid_.insert({ guid, new_entity });
|
||||
} catch (const std::exception& ex) {
|
||||
Logger::Root().Message(Logger::LOG_ERROR, "SYN", 27, ex.what());
|
||||
logger().Message(Logger::LOG_ERROR, "SYN", 27, ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2243,7 +2274,7 @@ void IfcFile::process_deletion_(IfcUtil::IfcBaseClass* entity) {
|
||||
if (it != byguid_.end()) {
|
||||
byguid_.erase(it);
|
||||
} else {
|
||||
Logger::Root().Warning("VAL", 19, "GlobalId on rooted instance not encountered in map");
|
||||
logger().Warning("VAL", 19, "GlobalId on rooted instance not encountered in map");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -110,6 +110,7 @@ Token GeneralTokenPtr(IfcSpfLexer* tokens, size_t start, const std::string& data
|
||||
class IFC_PARSE_API IfcSpfLexer {
|
||||
private:
|
||||
IfcCharacterDecoder* decoder_;
|
||||
Logger& logger_;
|
||||
size_t skipWhitespace() const;
|
||||
size_t skipComment() const;
|
||||
|
||||
@@ -120,7 +121,8 @@ class IFC_PARSE_API IfcSpfLexer {
|
||||
}
|
||||
FileReader* stream;
|
||||
// IfcFile* file;
|
||||
IfcSpfLexer(FileReader* stream);
|
||||
IfcSpfLexer(FileReader* stream, Logger& logger = Logger::Root());
|
||||
Logger& logger() const { return logger_; }
|
||||
Token Next();
|
||||
~IfcSpfLexer();
|
||||
void TokenString(size_t offset, std::string& result);
|
||||
|
||||
@@ -30,12 +30,12 @@ static const char* const DATA = "DATA";
|
||||
using namespace IfcParse;
|
||||
|
||||
namespace {
|
||||
IfcEntityInstanceData read_from_spf_file(IfcParse::impl::in_memory_file_storage* storage, const IfcParse::entity* decl) {
|
||||
IfcEntityInstanceData read_from_spf_file(IfcParse::impl::in_memory_file_storage* storage, const IfcParse::entity* decl, Logger& logger) {
|
||||
if (storage != nullptr) {
|
||||
parse_context pc;
|
||||
storage->tokens->Next();
|
||||
storage->load(-1, nullptr, pc, -1);
|
||||
return pc.construct(boost::none, *storage->references_to_resolve, decl, decl->as_entity()->attribute_count(), -1);
|
||||
return pc.construct(boost::none, *storage->references_to_resolve, decl, decl->as_entity()->attribute_count(), -1, logger);
|
||||
} else {
|
||||
// std::unreachable();
|
||||
return IfcEntityInstanceData(in_memory_attribute_storage(10));
|
||||
@@ -66,14 +66,19 @@ void IfcSpfHeader::readTerminal(const std::string& term, Trail trail) {
|
||||
}
|
||||
}
|
||||
|
||||
IfcParse::IfcSpfHeader::IfcSpfHeader(IfcParse::IfcFile* file)
|
||||
IfcParse::IfcSpfHeader::IfcSpfHeader(IfcParse::IfcFile* file, Logger& logger)
|
||||
: file_(file),
|
||||
logger_(logger),
|
||||
file_description_(nullptr),
|
||||
file_name_(nullptr),
|
||||
file_schema_(nullptr)
|
||||
{
|
||||
Header_section_schema::get_schema();
|
||||
|
||||
if (file != nullptr) {
|
||||
logger_ = file->logger();
|
||||
}
|
||||
|
||||
if (file == nullptr) {
|
||||
// overwritten later in IfcFile::setDefaultHeaderValues() when we know the schema identifier
|
||||
file_description_ = new Header_section_schema::file_description({}, "");
|
||||
@@ -101,11 +106,12 @@ IfcParse::IfcSpfHeader::IfcSpfHeader(IfcParse::IfcFile* file)
|
||||
}
|
||||
}
|
||||
|
||||
IfcParse::IfcSpfHeader::IfcSpfHeader(IfcParse::IfcSpfLexer* lexer)
|
||||
IfcParse::IfcSpfHeader::IfcSpfHeader(IfcParse::IfcSpfLexer* lexer, Logger& logger)
|
||||
: logger_(logger)
|
||||
{
|
||||
Header_section_schema::get_schema();
|
||||
|
||||
storage_ = new impl::in_memory_file_storage;
|
||||
storage_ = new impl::in_memory_file_storage(nullptr, logger_.get());
|
||||
storage_->tokens = lexer;
|
||||
file_ = nullptr;
|
||||
|
||||
@@ -128,6 +134,7 @@ void IfcParse::IfcSpfHeader::file(IfcParse::IfcFile* file)
|
||||
{
|
||||
this->file_ = file;
|
||||
if (file != nullptr) {
|
||||
logger_ = file->logger();
|
||||
storage_ = std::visit([this](auto& m) -> decltype(storage_) {
|
||||
if constexpr (std::is_same_v<std::decay_t<decltype(m)>, impl::in_memory_file_storage>) {
|
||||
return &m;
|
||||
@@ -153,19 +160,19 @@ void IfcSpfHeader::read() {
|
||||
|
||||
readTerminal(Header_section_schema::file_description::Class().name_uc(), NONE);
|
||||
delete file_description_;
|
||||
file_description_ = new Header_section_schema::file_description(read_from_spf_file(storage_, &Header_section_schema::file_description::Class()));
|
||||
file_description_ = new Header_section_schema::file_description(read_from_spf_file(storage_, &Header_section_schema::file_description::Class(), logger_.get()));
|
||||
file_description_->file_ = file_;
|
||||
readSemicolon();
|
||||
|
||||
readTerminal(Header_section_schema::file_name::Class().name_uc(), NONE);
|
||||
delete file_name_;
|
||||
file_name_ = new Header_section_schema::file_name(read_from_spf_file(storage_, &Header_section_schema::file_name::Class()));
|
||||
file_name_ = new Header_section_schema::file_name(read_from_spf_file(storage_, &Header_section_schema::file_name::Class(), logger_.get()));
|
||||
file_name_->file_ = file_;
|
||||
readSemicolon();
|
||||
|
||||
readTerminal(Header_section_schema::file_schema::Class().name_uc(), NONE);
|
||||
delete file_schema_;
|
||||
file_schema_ = new Header_section_schema::file_schema(read_from_spf_file(storage_, &Header_section_schema::file_schema::Class()));
|
||||
file_schema_ = new Header_section_schema::file_schema(read_from_spf_file(storage_, &Header_section_schema::file_schema::Class(), logger_.get()));
|
||||
file_schema_->file_ = file_;
|
||||
readSemicolon();
|
||||
}
|
||||
@@ -175,7 +182,7 @@ bool IfcSpfHeader::tryRead() {
|
||||
read();
|
||||
return true;
|
||||
} catch (const std::exception& e) {
|
||||
Logger::Root().Error("SYN", 28, e);
|
||||
logger_.get().Error("SYN", 28, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include "Header_section_schema.h"
|
||||
#include "storage.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace IfcParse {
|
||||
|
||||
class IfcFile;
|
||||
@@ -32,6 +34,7 @@ class IfcFile;
|
||||
class IFC_PARSE_API IfcSpfHeader {
|
||||
private:
|
||||
IfcFile* file_;
|
||||
std::reference_wrapper<Logger> logger_;
|
||||
IfcParse::impl::in_memory_file_storage* storage_ = nullptr;
|
||||
|
||||
mutable Header_section_schema::file_description* file_description_;
|
||||
@@ -45,13 +48,14 @@ class IFC_PARSE_API IfcSpfHeader {
|
||||
void readTerminal(const std::string& term, Trail trail);
|
||||
|
||||
public:
|
||||
explicit IfcSpfHeader(IfcParse::IfcFile* file = nullptr);
|
||||
explicit IfcSpfHeader(IfcParse::IfcSpfLexer* lexer);
|
||||
explicit IfcSpfHeader(IfcParse::IfcFile* file = nullptr, Logger& logger = Logger::Root());
|
||||
explicit IfcSpfHeader(IfcParse::IfcSpfLexer* lexer, Logger& logger = Logger::Root());
|
||||
|
||||
~IfcSpfHeader();
|
||||
|
||||
IfcParse::IfcFile* file() { return file_; }
|
||||
void file(IfcParse::IfcFile* file);
|
||||
Logger& logger() const { return logger_.get(); }
|
||||
|
||||
void read();
|
||||
bool tryRead();
|
||||
|
||||
@@ -206,11 +206,18 @@ class stack_node {
|
||||
};
|
||||
|
||||
struct ifcxml_parse_state {
|
||||
explicit ifcxml_parse_state(Logger& logger)
|
||||
: file(nullptr)
|
||||
, dialect(ifcxml_dialect_unknown)
|
||||
, logger(logger)
|
||||
{}
|
||||
|
||||
IfcParse::IfcFile* file;
|
||||
std::vector<stack_node> stack;
|
||||
std::map<std::string, int> idmap;
|
||||
std::vector<std::tuple<IfcUtil::IfcBaseEntity*, size_t, std::string>> forward_references;
|
||||
ifcxml_dialect dialect;
|
||||
Logger& logger;
|
||||
};
|
||||
|
||||
// ifc4 allows for aggregates to be concatenated using whitespace.
|
||||
@@ -227,7 +234,7 @@ std::vector<T> split(const std::string& value) {
|
||||
return r;
|
||||
}
|
||||
|
||||
boost::any parse_attribute_value(const IfcParse::parameter_type* ty, const std::string& value) {
|
||||
boost::any parse_attribute_value(const IfcParse::parameter_type* ty, const std::string& value, Logger& logger) {
|
||||
boost::any any;
|
||||
auto cpp_type = IfcUtil::from_parameter_type(ty);
|
||||
|
||||
@@ -255,7 +262,7 @@ boost::any parse_attribute_value(const IfcParse::parameter_type* ty, const std::
|
||||
}
|
||||
|
||||
if (any.empty()) {
|
||||
Logger::Root().Error("SYN", 29, "Attribute '" + value + "' not successfully parsed");
|
||||
logger.Error("SYN", 29, "Attribute '" + value + "' not successfully parsed");
|
||||
}
|
||||
|
||||
return any;
|
||||
@@ -293,7 +300,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::Root().Error("SYN", 30, "Mismatch in parse stack due to previous errors");
|
||||
state->logger.Error("SYN", 30, "Mismatch in parse stack due to previous errors");
|
||||
} else {
|
||||
state->stack.pop_back();
|
||||
}
|
||||
@@ -318,9 +325,9 @@ static void process_characters(void* user, const xmlChar* character, int len) {
|
||||
const auto* pt = state->stack.back().inst()->declaration().as_type_declaration()->declared_type();
|
||||
boost::any val;
|
||||
try {
|
||||
val = parse_attribute_value(pt, txt);
|
||||
val = parse_attribute_value(pt, txt, state->logger);
|
||||
} catch (const std::exception& e) {
|
||||
Logger::Root().Error("SYN", 31, e, state->stack.back().inst());
|
||||
state->logger.Error("SYN", 31, e, state->stack.back().inst());
|
||||
}
|
||||
if (!val.empty()) {
|
||||
// type declaration always at idx 0
|
||||
@@ -348,13 +355,13 @@ static void process_characters(void* user, const xmlChar* character, int len) {
|
||||
} else if (tagname == "documentation") {
|
||||
header.file_description()->setdescription({txt});
|
||||
} else {
|
||||
Logger::Root().Error("SYN", 32, "Unrecognized header entry " + tagname);
|
||||
state->logger.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();
|
||||
auto cpp_type = IfcUtil::from_parameter_type(pt);
|
||||
if (cpp_type != IfcUtil::Argument_ENTITY_INSTANCE) {
|
||||
auto val = parse_attribute_value(pt, txt);
|
||||
auto val = parse_attribute_value(pt, txt, state->logger);
|
||||
if (!val.empty()) {
|
||||
visit_any([&state](auto& v) {
|
||||
state->stack.back().inst()->set_attribute_value(state->stack.back().idx(), v);
|
||||
@@ -363,7 +370,7 @@ static void process_characters(void* user, const xmlChar* character, int len) {
|
||||
}
|
||||
} else if (state_type == stack_node::node_aggregate_element) {
|
||||
const auto* pt = state->stack.back().aggregate_elem_type();
|
||||
auto val = parse_attribute_value(pt, txt);
|
||||
auto val = parse_attribute_value(pt, txt, state->logger);
|
||||
if (!val.empty()) {
|
||||
(*(state->stack.rbegin() + 1)).aggregate_elements.push_back(val);
|
||||
}
|
||||
@@ -417,12 +424,12 @@ static void start_element(void* user, const xmlChar* tag, const xmlChar** attrs)
|
||||
if (it != end) {
|
||||
std::string schema_name(&it->front(), it->size());
|
||||
boost::to_upper(schema_name);
|
||||
state->file = new IfcParse::IfcFile(IfcParse::schema_by_name(schema_name));
|
||||
state->file = new IfcParse::IfcFile(IfcParse::schema_by_name(schema_name), IfcParse::FT_AUTODETECT, "", state->logger);
|
||||
state->dialect = ifcxml_dialect_ifc4;
|
||||
}
|
||||
goto end;
|
||||
} else if (tagname == "ex:iso_10303_28" && attrname == "xsi:schemaLocation" && boost::starts_with(value, "http://www.iai-tech.org/ifcXML/IFC2x3")) {
|
||||
state->file = new IfcParse::IfcFile(IfcParse::schema_by_name("IFC2X3"));
|
||||
state->file = new IfcParse::IfcFile(IfcParse::schema_by_name("IFC2X3"), IfcParse::FT_AUTODETECT, "", state->logger);
|
||||
state->dialect = ifcxml_dialect_ifc2x3;
|
||||
goto end;
|
||||
}
|
||||
@@ -491,14 +498,14 @@ static void start_element(void* user, const xmlChar* tag, const xmlChar** attrs)
|
||||
auto idx = entity->attribute_index(pair.first);
|
||||
if (idx != -1) {
|
||||
const auto* attr = entity->attribute_by_index(idx);
|
||||
auto val = parse_attribute_value(attr->type_of_attribute(), pair.second);
|
||||
auto val = parse_attribute_value(attr->type_of_attribute(), pair.second, state->logger);
|
||||
if (!val.empty()) {
|
||||
visit_any([&untyped, idx](auto& v) {
|
||||
untyped.set_attribute_value(idx, v);
|
||||
}, val);
|
||||
}
|
||||
} else {
|
||||
Logger::Root().Error("SYN", 33, "Unknown attribute '" + pair.first + "' on entity '" + entity->name() + "' with value '" + pair.second + "'");
|
||||
state->logger.Error("SYN", 33, "Unknown attribute '" + pair.first + "' on entity '" + entity->name() + "' with value '" + pair.second + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -556,7 +563,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::Root().Error("SYN", 34, e);
|
||||
state->logger.Error("SYN", 34, e);
|
||||
}
|
||||
if (decl != nullptr) {
|
||||
auto inst_or_ref = create_instance(decl);
|
||||
@@ -571,7 +578,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::Root().Error("SYN", 35, "'" + state->stack.back().inst()->declaration().name() + "' is not an entity, unable to set attribute '" + tagname + "'");
|
||||
state->logger.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 +589,7 @@ static void start_element(void* user, const xmlChar* tag, const xmlChar** attrs)
|
||||
return attr->name() == tagname;
|
||||
});
|
||||
if (found == inverses.end()) {
|
||||
Logger::Root().Error("SYN", 36, "Unknown attribute " + tagname);
|
||||
state->logger.Error("SYN", 36, "Unknown attribute " + tagname);
|
||||
state->stack.push_back(state->stack.back());
|
||||
} else {
|
||||
if ((*found)->bound1() == 0 && (*found)->bound2() == 1) {
|
||||
@@ -595,7 +602,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::Root().Error("SYN", 37, "Unknown attribute " + tagname);
|
||||
state->logger.Error("SYN", 37, "Unknown attribute " + tagname);
|
||||
state->stack.push_back(state->stack.back());
|
||||
}
|
||||
} else {
|
||||
@@ -642,7 +649,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::Root().Error("SYN", 38, e);
|
||||
state->logger.Error("SYN", 38, e);
|
||||
}
|
||||
|
||||
if (decl == nullptr) {
|
||||
@@ -651,7 +658,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::Root().Error("SYN", 39, "Not an entity definition " + tagname);
|
||||
state->logger.Error("SYN", 39, "Not an entity definition " + tagname);
|
||||
goto end;
|
||||
}
|
||||
|
||||
@@ -665,7 +672,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::Root().Error("SYN", 40, "Internal error, inverse attribute not processed");
|
||||
state->logger.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);
|
||||
@@ -688,12 +695,10 @@ end:
|
||||
return;
|
||||
}
|
||||
|
||||
IFC_PARSE_API IfcParse::IfcFile* IfcParse::parse_ifcxml(const std::string& filename) {
|
||||
IFC_PARSE_API IfcParse::IfcFile* IfcParse::parse_ifcxml(const std::string& filename, Logger& logger) {
|
||||
throw std::runtime_error("IFC-XML import temporarily disabled");
|
||||
|
||||
ifcxml_parse_state state;
|
||||
state.file = nullptr;
|
||||
state.dialect = ifcxml_dialect_unknown;
|
||||
ifcxml_parse_state state(logger);
|
||||
|
||||
xmlSAXHandler handler;
|
||||
memset(&handler, 0, sizeof(xmlSAXHandler));
|
||||
|
||||
@@ -20,9 +20,11 @@ namespace rocksdb {
|
||||
#include "map_transformer.h"
|
||||
#include "set_to_map_transformer.h"
|
||||
#include "file_open_status.h"
|
||||
#include "IfcLogger.h"
|
||||
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <variant>
|
||||
#include <iterator>
|
||||
#include <cstdint>
|
||||
@@ -187,7 +189,7 @@ namespace IfcParse {
|
||||
|
||||
void push(IfcUtil::IfcBaseClass* inst);
|
||||
|
||||
IfcEntityInstanceData construct(boost::optional<size_t> name, unresolved_references& references_to_resolve, const IfcParse::declaration* decl, boost::optional<size_t> expected_size, int resolve_reference_index, bool coerce_attribute_count=true);
|
||||
IfcEntityInstanceData construct(boost::optional<size_t> name, unresolved_references& references_to_resolve, const IfcParse::declaration* decl, boost::optional<size_t> expected_size, int resolve_reference_index, Logger& logger, bool coerce_attribute_count=true);
|
||||
};
|
||||
|
||||
namespace impl {
|
||||
@@ -198,6 +200,7 @@ namespace IfcParse {
|
||||
}
|
||||
|
||||
IfcParse::IfcSpfLexer* tokens;
|
||||
std::reference_wrapper<Logger> logger_;
|
||||
// IfcParse::FileReader* stream;
|
||||
|
||||
// Either one of these needs to be set
|
||||
@@ -219,9 +222,10 @@ namespace IfcParse {
|
||||
typedef std::map<inverse_attr_record, std::vector<uint32_t>> entities_by_ref_t;
|
||||
typedef entity_instance_by_name_t::iterator iterator;
|
||||
|
||||
in_memory_file_storage(IfcParse::IfcFile* f = nullptr) : tokens(nullptr), file(f), schema(nullptr) {}
|
||||
in_memory_file_storage(IfcParse::IfcFile* f = nullptr, Logger& logger = Logger::Root()) : tokens(nullptr), logger_(logger), file(f), schema(nullptr) {}
|
||||
in_memory_file_storage(const in_memory_file_storage&) = delete;
|
||||
in_memory_file_storage(const in_memory_file_storage&&) = delete;
|
||||
Logger& logger() const { return logger_.get(); }
|
||||
|
||||
|
||||
class type_iterator : public entities_by_type_t::const_iterator {
|
||||
|
||||
@@ -19,7 +19,7 @@ RocksDbSerializer::RocksDbSerializer(IfcParse::IfcFile* file, const std::string&
|
||||
options.merge_operator.reset(new ConcatenateIdMergeOperator());
|
||||
rocksdb::Status status = rocksdb::DB::Open(options, rocksdb_filename, &db_);*/
|
||||
|
||||
output_file_ = new IfcParse::IfcFile(file->schema(), IfcParse::FT_ROCKSDB, rocksdb_filename_);
|
||||
output_file_ = new IfcParse::IfcFile(file->schema(), IfcParse::FT_ROCKSDB, rocksdb_filename_, logger);
|
||||
|
||||
// We promise never to add the same instance twice
|
||||
output_file_->check_existance_before_adding = false;
|
||||
|
||||
Reference in New Issue
Block a user