MCPcopy Create free account
hub / github.com/IfcOpenShell/IfcOpenShell / loop_to_function_item_upgrade_impl

Method loop_to_function_item_upgrade_impl

src/ifcgeom/taxonomy.cpp:824–888  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

822
823
824boost::optional<function_item::ptr> ifcopenshell::geometry::taxonomy::loop_to_function_item_upgrade_impl(ptr item) {
825 boost::optional<function_item::ptr> function_item_;
826 auto loop_ = dcast<loop>(item);
827 if (loop_) {
828 if (loop_->function_item.is_initialized()) {
829 function_item_ = loop_->function_item;
830 } else {
831 // piecewise_function is a specialization of function_item - callers don't need to know this detail
832 piecewise_function::spans_t spans;
833 spans.reserve(loop_->children.size());
834 for (auto& edge_ : loop_->children) {
835 if (edge_->basis && edge_->basis->kind() == CIRCLE) {
836 const circle::ptr circ = std::static_pointer_cast<circle>(edge_->basis);
837
838 auto* s_pnt = boost::get<point3::ptr>(&edge_->start);
839 auto* e_pnt = boost::get<point3::ptr>(&edge_->end);
840 auto* s_param = boost::get<double>(&edge_->start);
841 auto* e_param = boost::get<double>(&edge_->end);
842
843 if (!s_pnt && !s_param) {
844 return boost::none;
845 }
846 if (!e_pnt && !e_param) {
847 return boost::none;
848 }
849
850 double s = s_pnt ? project_onto_curve(circ, **s_pnt) : *s_param;
851 double e = e_pnt ? project_onto_curve(circ, **e_pnt) : *e_param;
852
853 auto l = std::fabs(s - e) * circ->radius;
854 std::function<Eigen::Matrix4d(double)> fn = [circ, s](double u) {
855 point3 P;
856 direction3 d;
857 evaluate_curve(circ, u / circ->radius + s, P);
858 evaluate_curve_d1(circ, u / circ->radius + s, d);
859 return matrix4(P.ccomponents(), circ->matrix->ccomponents().col(2).head<3>(), d.ccomponents()).components();
860 };
861 spans.emplace_back(taxonomy::make<taxonomy::functor_item>(l, fn));
862 } else if (edge_->start.which() == 1 && edge_->end.which() == 1) {
863 if (edge_->basis && edge_->basis->kind() != LINE) {
864 Logger::Message(Logger::Severity::LOG_WARNING, "Basis curve not supported - edge is treated as a straight line edge");
865 }
866 const auto& s = boost::get<point3::ptr>(edge_->start)->ccomponents();
867 const auto& e = boost::get<point3::ptr>(edge_->end)->ccomponents();
868 Eigen::Vector3d v = e - s;
869 auto l = v.norm(); // the norm of a vector is a measure of its length
870 v.normalize(); // normalize the vector so that it is a unit direction vector
871 std::function<Eigen::Matrix4d(double)> fn = [s, v](double u) {
872 Eigen::Vector3d o(s + u * v), axis(0, 0, 1), refDirection(v);
873 auto Y = axis.cross(refDirection).normalized();
874 axis = refDirection.cross(Y).normalized();
875 return make<matrix4>(o, axis, refDirection)->components();
876 };
877 spans.emplace_back(taxonomy::make<taxonomy::functor_item>(l, fn));
878 } else {
879 Logger::Message(Logger::Severity::LOG_ERROR, "Basis curve not supported");
880 return boost::none;
881 }

Callers

nothing calls this directly

Calls 9

evaluate_curve_d1Function · 0.85
matrix4Function · 0.85
MessageClass · 0.85
reserveMethod · 0.80
normMethod · 0.80
project_onto_curveFunction · 0.70
evaluate_curveFunction · 0.70
sizeMethod · 0.45
kindMethod · 0.45

Tested by

no test coverage detected