From f12c3aae09f0bb8a981ffdab19a39c2b32a6e5ed Mon Sep 17 00:00:00 2001 From: Richard Brice <37087370+RickBrice@users.noreply.github.com> Date: Mon, 15 Jan 2024 15:52:26 -0800 Subject: [PATCH] Adds caching of loop upgraded to pwf to loop class --- src/ifcgeom/taxonomy.h | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/src/ifcgeom/taxonomy.h b/src/ifcgeom/taxonomy.h index c15c413493..a9c5b88161 100644 --- a/src/ifcgeom/taxonomy.h +++ b/src/ifcgeom/taxonomy.h @@ -759,6 +759,7 @@ typedef item const* ptr; DECLARE_PTR(loop) boost::optional external, closed; + boost::optional pwf; bool is_polyhedron() const { for (auto& e : children) { @@ -1130,25 +1131,30 @@ typedef item const* ptr; loop_to_piecewise_function_upgrade(taxonomy::ptr item) { auto loop = taxonomy::dcast(item); if (loop) { - pwf_ = taxonomy::make(); - for (auto& edge : loop->children) { - // the edge could be an arc or trimmed circle in the case of IfcIndexPolyCurve - support for this isn't implemented yet - if (edge->basis) { - Logger::Message(Logger::Severity::LOG_NOTICE, "Shape of basis curve ignored - edge is treated as a straight line edge"); - } + if (loop->pwf.is_initialized()) { + pwf_ = loop->pwf; + } else { + pwf_ = taxonomy::make(); + for (auto& edge : loop->children) { + // the edge could be an arc or trimmed circle in the case of IfcIndexPolyCurve - support for this isn't implemented yet + if (edge->basis) { + Logger::Message(Logger::Severity::LOG_NOTICE, "Shape of basis curve ignored - edge is treated as a straight line edge"); + } - const auto& s = boost::get(edge->start)->ccomponents(); - const auto& e = boost::get(edge->end)->ccomponents(); - Eigen::Vector3d v = e - s; - auto l = v.norm(); // the norm of a vector is a measure of its length - v.normalize(); // normalize the vector so that it is a unit direction vector - std::function fn = [s, v](double u) { - Eigen::Vector3d o(s + u * v), axis(0, 0, 1), refDirection(v); - auto Y = axis.cross(refDirection).normalized(); - axis = refDirection.cross(Y).normalized(); - return taxonomy::make(o, axis, refDirection)->components(); - }; - (*pwf_)->spans.emplace_back(l, fn); + const auto& s = boost::get(edge->start)->ccomponents(); + const auto& e = boost::get(edge->end)->ccomponents(); + Eigen::Vector3d v = e - s; + auto l = v.norm(); // the norm of a vector is a measure of its length + v.normalize(); // normalize the vector so that it is a unit direction vector + std::function fn = [s, v](double u) { + Eigen::Vector3d o(s + u * v), axis(0, 0, 1), refDirection(v); + auto Y = axis.cross(refDirection).normalized(); + axis = refDirection.cross(Y).normalized(); + return taxonomy::make(o, axis, refDirection)->components(); + }; + (*pwf_)->spans.emplace_back(l, fn); + } + loop->pwf = pwf_; } } }