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:
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user