From 37315e941a6d0fd08877f48ac2d74cc26fdf30da Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Wed, 11 Sep 2024 11:56:49 +0500 Subject: [PATCH] taxonomy.h - move upgrades code to cpp --- src/ifcgeom/taxonomy.cpp | 153 +++++++++++++++++++++++++++++++++++++++ src/ifcgeom/taxonomy.h | 135 +++------------------------------- 2 files changed, 165 insertions(+), 123 deletions(-) diff --git a/src/ifcgeom/taxonomy.cpp b/src/ifcgeom/taxonomy.cpp index 9b4f5043aa..0c78b84601 100644 --- a/src/ifcgeom/taxonomy.cpp +++ b/src/ifcgeom/taxonomy.cpp @@ -599,3 +599,156 @@ void ifcopenshell::geometry::taxonomy::extrusion::print(std::ostream& o, int ind direction->print(o, indent + 4); basis->print(o, indent + 4); } + +boost::optional ifcopenshell::geometry::taxonomy::loop_to_face_upgrade_impl(ptr item) { + boost::optional face_; + auto loop_ = dcast(item); + if (loop_) { + loop_->external = true; + + face_ = make(); + (*face_)->instance = loop_->instance; + (*face_)->matrix = loop_->matrix; + (*face_)->children = { clone(loop_) }; + } + return face_; +} + +boost::optional ifcopenshell::geometry::taxonomy::curve_to_edge_upgrade_impl(ptr item) { + boost::optional edge_; + auto circle_ = dcast(item); + auto ellipse_ = dcast(item); + auto line_ = dcast(item); + auto bspline_curve_ = dcast(item); + if (circle_ || ellipse_ || line_ || bspline_curve_) { + edge_ = make(); + if (circle_) { + (*edge_)->basis = circle_; + } else if (ellipse_) { + (*edge_)->basis = ellipse_; + } else if (line_) { + (*edge_)->basis = line_; + } else if (bspline_curve_) { + (*edge_)->basis = bspline_curve_; + } + + if (circle_ || ellipse_) { + // @todo + (*edge_)->start = 0.; + (*edge_)->end = 2 * boost::math::constants::pi(); + } + } + return edge_; +} + +boost::optional ifcopenshell::geometry::taxonomy::curve_to_loop_upgrade_impl(ptr item) { + boost::optional loop_; + auto circle_ = dcast(item); + auto ellipse_ = dcast(item); + auto line_ = dcast(item); + auto bspline_curve_ = dcast(item); + if (circle_ || ellipse_ || line_ || bspline_curve_) { + auto edge_ = make(); + if (circle_) { + edge_->basis = circle_; + } else if (ellipse_) { + edge_->basis = ellipse_; + } else if (line_) { + edge_->basis = line_; + } else if (bspline_curve_) { + edge_->basis = bspline_curve_; + } + + if (circle_ || ellipse_) { + // @todo + edge_->start = 0.; + edge_->end = 2 * boost::math::constants::pi(); + } + + loop_ = make(); + (*loop_)->children.push_back(edge_); + } + return loop_; +} + +boost::optional ifcopenshell::geometry::taxonomy::edge_to_loop_upgrade_impl(ptr item) { + boost::optional loop_; + auto edge_ = dcast(item); + if (edge_) { + loop_ = make(); + (*loop_)->children.push_back(edge_); + } + return loop_; +} + +boost::optional ifcopenshell::geometry::taxonomy::curve_to_face_upgrade_impl(ptr item) { + boost::optional face_; + auto circle_ = dcast(item); + auto ellipse_ = dcast(item); + auto line_ = dcast(item); + auto bspline_curve_ = dcast(item); + + if (circle_ || ellipse_ || line_ || bspline_curve_) { + auto edge_ = make(); + if (circle_) { + edge_->basis = circle_; + } else if (ellipse_) { + edge_->basis = ellipse_; + } else if (line_) { + edge_->basis = line_; + } else if (bspline_curve_) { + edge_->basis = bspline_curve_; + } + + if (circle_ || ellipse_) { + // @todo + edge_->start = 0.; + edge_->end = 2 * boost::math::constants::pi(); + } + + auto loop_ = make(); + loop_->children.push_back(edge_); + + face_ = make(); + (*face_)->instance = loop_->instance; + (*face_)->matrix = loop_->matrix; + (*face_)->children = { clone(loop_) }; + } + return face_; +} + + +boost::optional ifcopenshell::geometry::taxonomy::loop_to_piecewise_function_upgrade_impl(ptr item) { + boost::optional pwf_; + auto loop_ = dcast(item); + if (loop_) { + if (loop_->pwf.is_initialized()) { + pwf_ = loop_->pwf; + } else { + piecewise_function::spans_t spans; + spans.reserve(loop_->children.size()); + 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 make(o, axis, refDirection)->components(); + }; + spans.emplace_back(l, fn); + } + pwf_ = make(0.0,spans); + loop_->pwf = pwf_; + } + } + return pwf_; +} diff --git a/src/ifcgeom/taxonomy.h b/src/ifcgeom/taxonomy.h index 3b77273240..40e738d1d8 100644 --- a/src/ifcgeom/taxonomy.h +++ b/src/ifcgeom/taxonomy.h @@ -1089,6 +1089,7 @@ typedef item const* ptr; static const size_t max = std::tuple_size::value; }; + boost::optional loop_to_face_upgrade_impl(ptr item); template class loop_to_face_upgrade { private: @@ -1096,15 +1097,7 @@ typedef item const* ptr; public: loop_to_face_upgrade(taxonomy::ptr item) { if constexpr (std::is_same_v) { - auto loop = taxonomy::dcast(item); - if (loop) { - loop->external = true; - - face_ = taxonomy::make(); - (*face_)->instance = loop->instance; - (*face_)->matrix = loop->matrix; - (*face_)->children = { taxonomy::clone(loop) }; - } + face_ = loop_to_face_upgrade_impl(item); } } @@ -1122,6 +1115,7 @@ typedef item const* ptr; } }; + boost::optional curve_to_edge_upgrade_impl(ptr item); template class curve_to_edge_upgrade { private: @@ -1129,28 +1123,7 @@ typedef item const* ptr; public: curve_to_edge_upgrade(taxonomy::ptr item) { if constexpr (std::is_same_v) { - auto circle = taxonomy::dcast(item); - auto ellipse = taxonomy::dcast(item); - auto line = taxonomy::dcast(item); - auto bspline_curve = taxonomy::dcast(item); - if (circle || ellipse || line || bspline_curve) { - edge_ = taxonomy::make(); - if (circle) { - (*edge_)->basis = circle; - } else if (ellipse) { - (*edge_)->basis = ellipse; - } else if (line) { - (*edge_)->basis = line; - } else if (bspline_curve) { - (*edge_)->basis = bspline_curve; - } - - if (circle || ellipse) { - // @todo - (*edge_)->start = 0.; - (*edge_)->end = 2 * boost::math::constants::pi(); - } - } + edge_ = taxonomy::curve_to_edge_upgrade_impl(item); } } @@ -1168,7 +1141,7 @@ typedef item const* ptr; } }; - + boost::optional curve_to_loop_upgrade_impl(ptr item); template class curve_to_loop_upgrade { private: @@ -1176,31 +1149,7 @@ typedef item const* ptr; public: curve_to_loop_upgrade(taxonomy::ptr item) { if constexpr (std::is_same_v) { - auto circle = taxonomy::dcast(item); - auto ellipse = taxonomy::dcast(item); - auto line = taxonomy::dcast(item); - auto bspline_curve = taxonomy::dcast(item); - if (circle || ellipse || line || bspline_curve) { - auto edge = taxonomy::make(); - if (circle) { - edge->basis = circle; - } else if (ellipse) { - edge->basis = ellipse; - } else if (line) { - edge->basis = line; - } else if (bspline_curve) { - edge->basis = bspline_curve; - } - - if (circle || ellipse) { - // @todo - edge->start = 0.; - edge->end = 2 * boost::math::constants::pi(); - } - - loop_ = taxonomy::make(); - (*loop_)->children.push_back(edge); - } + loop_ = curve_to_loop_upgrade_impl(item); } } @@ -1218,6 +1167,7 @@ typedef item const* ptr; } }; + boost::optional edge_to_loop_upgrade_impl(ptr item); template class edge_to_loop_upgrade { private: @@ -1225,11 +1175,7 @@ typedef item const* ptr; public: edge_to_loop_upgrade(taxonomy::ptr item) { if constexpr (std::is_same_v) { - auto edge = taxonomy::dcast(item); - if (edge) { - loop_ = taxonomy::make(); - (*loop_)->children.push_back(edge); - } + loop_ = edge_to_loop_upgrade_impl(item); } } @@ -1247,7 +1193,7 @@ typedef item const* ptr; } }; - + boost::optional curve_to_face_upgrade_impl(ptr item); template class curve_to_face_upgrade { private: @@ -1255,36 +1201,7 @@ typedef item const* ptr; public: curve_to_face_upgrade(taxonomy::ptr item) { if constexpr (std::is_same_v) { - auto circle = taxonomy::dcast(item); - auto ellipse = taxonomy::dcast(item); - auto line = taxonomy::dcast(item); - auto bspline_curve = taxonomy::dcast(item); - if (circle || ellipse || line || bspline_curve) { - auto edge = taxonomy::make(); - if (circle) { - edge->basis = circle; - } else if (ellipse) { - edge->basis = ellipse; - } else if (line) { - edge->basis = line; - } else if (bspline_curve) { - edge->basis = bspline_curve; - } - - if (circle || ellipse) { - // @todo - edge->start = 0.; - edge->end = 2 * boost::math::constants::pi(); - } - - auto loop = taxonomy::make(); - loop->children.push_back(edge); - - face_ = taxonomy::make(); - (*face_)->instance = loop->instance; - (*face_)->matrix = loop->matrix; - (*face_)->children = { taxonomy::clone(loop) }; - } + face_ = curve_to_face_upgrade_impl(item); } } @@ -1302,6 +1219,7 @@ typedef item const* ptr; } }; + boost::optional loop_to_piecewise_function_upgrade_impl(ptr item); template class loop_to_piecewise_function_upgrade { private: @@ -1310,36 +1228,7 @@ typedef item const* ptr; public: loop_to_piecewise_function_upgrade(taxonomy::ptr item) { if constexpr (std::is_same_v) { - auto loop = taxonomy::dcast(item); - if (loop) { - if (loop->pwf.is_initialized()) { - pwf_ = loop->pwf; - } else { - taxonomy::piecewise_function::spans_t spans; - spans.reserve(loop->children.size()); - 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(); - }; - spans.emplace_back(l, fn); - } - pwf_ = taxonomy::make(0.0,spans); - loop->pwf = pwf_; - } - } + pwf_ = loop_to_piecewise_function_upgrade_impl(item); } }