You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123 lines
3.3 KiB
C++

/**
* @file
* @brief IO filtering class for ScanIO to discard unwanted points.
*
* @author Thomas Escher
*/
#ifndef POINT_FILTER_H
#define POINT_FILTER_H
#include <string>
#include <map>
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<std::string, std::string> 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<typename T> friend struct CheckerFactory;
static std::map<std::string, Checker* (*)(const std::string&)>* 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<typename T>
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<T>::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