/** * @file * @brief IO filtering class for ScanIO to discard unwanted points. * * @author Thomas Escher */ #ifndef POINT_FILTER_H #define POINT_FILTER_H #include #include class Checker; /** * Flexible filtering class for parsing a set of points. * * This class is configurable with parameters for range and height and can be transferred via the use of a parameter string. * Use on a point set via repeated use of the check function, which creates the internal Checker structures once for each change to the parameters. The amount of tests is held as minimal as possible. */ class PointFilter { public: // Default empty constructor PointFilter(); //! Deserialization constructor, forms parameters back from a string given by getParams PointFilter(const std::string& params); ~PointFilter(); PointFilter& setRange(double maxDist, double minDist); PointFilter& setHeight(double top, double bottom); PointFilter& setRangeMutator(double range); //! Serialization function to convert it into a string, usable in the constructor std::string getParams(); //! Check a point, returning success if all contained Checker functions accept that point (implemented in .icc) inline bool check(double* point); private: //! Storage for parameter keys and values std::map m_params; //! If either not created yet or parameters get changed, this flag will cause check to create a new Checker chain bool m_changed; //! created in the first check call with the changed flag set Checker* m_checker; //! Allocation of the checkers void createCheckers(); // factory magic template friend struct CheckerFactory; static std::map* factory; }; class Checker { public: Checker(); ~Checker(); //! Testing function virtual bool test(double* point) = 0; //! Next test in chain Checker* m_next; }; //! Factory integrating the create-function and adding it to the lookup map in an easy template template struct CheckerFactory { //! Instanciate in the source code with the to be created class as template argument and associated key string as constructor argument CheckerFactory(const std::string& key) { (*PointFilter::factory)[key] = CheckerFactory::create; } //! Automated create function, safely returning a nullpointer if the constructor throws for unwanted values static Checker* create(const std::string& value) { try { return new T(value); } catch(...) { return 0; } } }; class CheckerRangeMax : public Checker { public: CheckerRangeMax(const std::string& value); virtual bool test(double* point); private: double m_max; }; class CheckerRangeMin : public Checker { public: CheckerRangeMin(const std::string& value); virtual bool test(double* point); private: double m_min; }; class CheckerHeightTop : public Checker { public: CheckerHeightTop(const std::string& value); virtual bool test(double* point); private: double m_top; }; class CheckerHeightBottom : public Checker { public: CheckerHeightBottom(const std::string& value); virtual bool test(double* point); private: double m_bottom; }; class RangeMutator : public Checker { public: RangeMutator(const std::string& value); virtual bool test(double* point); private: double m_range; }; #include "pointfilter.icc" #endif //POINT_FILTER_H