#ifndef ITERATOR_PWF_EVALUATOR_H #define ITERATOR_PWF_EVALUATOR_H #include "../ifcgeom/taxonomy.h" #include namespace ifcopenshell { namespace geometry { /// @brief Computes a point on a helmert curve at s. /// Returns (x,y,theta) at L/2. The results are in a vector so they can be returned to python IFC_GEOM_API std::vector helmert_curve_point(double A0, double A1, double A2, double s); /// @brief Converts a loop to a function item. /// This is intended to be used from python side. Polylines are mapped to a loop, but when /// representing an alignment they need to be a function_item so the can be evaluated by function_item_evaluator. /// On the C++ side, the dcast operator take care of this, but dcast is not accessible on the python side. /// @param loop /// @return static taxonomy::function_item::ptr convert_loop_to_function_item(taxonomy::loop::ptr loop) { return ifcopenshell::geometry::taxonomy::dcast(loop); } /// @brief Abstract class for evaluating a function_item. This class is specialized for each of the function_item types. struct IFC_GEOM_API fn_evaluator { fn_evaluator(const ifcopenshell::geometry::Settings& settings, Logger& logger = Logger::Root()) : settings_(settings), logger_(logger) { } fn_evaluator(const fn_evaluator& other) = default; virtual ~fn_evaluator() = default; virtual fn_evaluator* clone() const = 0; virtual Eigen::Matrix4d evaluate(double u) const = 0; virtual double start() const = 0; virtual double end() const = 0; double length() const { return end() - start(); } ifcopenshell::geometry::Settings settings_; protected: Logger& logger_; }; /// @brief utility class to evaluate function_item objects. class IFC_GEOM_API function_item_evaluator { public: function_item_evaluator(const ifcopenshell::geometry::Settings& settings, taxonomy::function_item::const_ptr fn, Logger& logger = Logger::Root()); function_item_evaluator(const function_item_evaluator& other); ~function_item_evaluator(); /// @brief returns a vector of "distance along" points where the evaluate function computes loop points std::vector evaluation_points() const; /// @brief returns a vector of "distance along" points between ustart and uend /// @param ustart starting location /// @param uend ending location /// @param nsteps number of steps to evaluate std::vector evaluation_points(double ustart, double uend, unsigned nsteps) const; /// @brief evaluates the function between start and end /// evaluation point step size is taken from the settings object taxonomy::item::ptr evaluate() const; /// @brief evaluates the function between ustart and uend /// if ustart and uend are out of range, the range of values evaluated /// are constrained to start_ and start_+length_ /// @param ustart starting location /// @param uend ending location /// @param nsteps number of steps to evaluate /// @return taxonomy::loop::ptr taxonomy::item::ptr evaluate(double ustart, double uend, unsigned nsteps) const; /// @brief evaluates the function at u /// @param u u is constrained to be between start_ and start_+length /// @return 4x4 placement matrix. Curvature values for horizontal, vertical, and vertical + cant are stored in the last row. Eigen::Matrix4d evaluate(double u) const; private: taxonomy::item::ptr evaluate(const std::vector& dist) const; fn_evaluator* fn_evaluator_ = nullptr; mutable boost::optional> eval_points_; // cache evaluation points Logger& logger_; }; }} #endif