#pragma once #include #include #include "utils.h" //! @brief Base class for all waypoint managers. template class Container /*e.g. QVector*/> class GenericSlicer { public: typedef Container ContainerType; GenericSlicer(); // Slicing. void slice (const ContainerType &source, ContainerType &slice); void next (const ContainerType &source, ContainerType &slice); void previous (const ContainerType &source, ContainerType &slice); void reset (const ContainerType &source, ContainerType &slice); // Slicing parameters. //! @brief Sets the overlap. //! //! @param overlap The number of overlapping vertices //! between on and the next slice. void setOverlap (uint32_t overlap); //! @brief Sets the number of vertices per slice. //! //! @param N The number of vertices per slice. void setN (std::uint32_t N); //! @brief Sets the start index. //! //! @param idxStart The start index. void setStartIndex (int idxStart); //! @return Returns the overlap. uint32_t overlap (); //! @return Returns the number of vertices per slice N. uint32_t N (); //! @return Returns the start index. int startIndex (); private: void _updateIdx(std::size_t size); long _idxStart; long _idxEnd; long _idxNext; long _idxPrevious; uint32_t _overlap; uint32_t _N; bool _idxValid; bool _atEnd; }; template class Container /*e.g. QVector*/> GenericSlicer::GenericSlicer(): _idxValid(false) , _atEnd(false) {} template class Container /*e.g. QVector*/> void GenericSlicer::setOverlap(std::uint32_t overlap) { _idxValid = false; _overlap = overlap; } template class Container /*e.g. QVector*/> void GenericSlicer::setN(uint32_t N) { _idxValid = false; _N = N > 0 ? N : 1; } template class Container /*e.g. QVector*/> void GenericSlicer::setStartIndex(int idxStart) { _idxValid = false; _idxStart = idxStart; } template class Container /*e.g. QVector*/> uint32_t GenericSlicer::overlap() { return _overlap; } template class Container /*e.g. QVector*/> uint32_t GenericSlicer::N() { return _N; } template class Container /*e.g. QVector*/> int GenericSlicer::startIndex() { return _idxStart; } template class Container /*e.g. QVector*/> void GenericSlicer::_updateIdx(std::size_t size) { _idxValid = true; _atEnd = false; if ( _idxStart >= size-1 ) { _idxStart = size-1; _idxEnd = _idxStart; _idxNext = _idxStart; _atEnd = true; return; } _idxStart < 0 ? 0 : _idxStart; _idxEnd = _idxStart + _N - 1; _idxEnd = _idxEnd < size ? _idxEnd : size-1; _idxNext = _idxEnd + 1 - _overlap; _idxNext = _idxNext < 0 ? 0 : _idxNext; _idxNext = _idxNext < size ? _idxNext : size-1; _idxPrevious = _idxStart - 1 + _overlap; _idxPrevious = _idxPrevious < 0 ? 0 : _idxPrevious; _idxPrevious = _idxPrevious < size ? _idxPrevious : size-1; } template class Container /*e.g. QVector*/> void GenericSlicer::slice(const ContainerType &source, Container &slice){ if ( !_idxValid) _updateIdx(source.size()); WaypointManager::Utils::extract(source, slice, _idxStart, _idxEnd); // extract waypoints } template class Container /*e.g. QVector*/> void GenericSlicer::next(const ContainerType &source, Container &slice){ setStartIndex(_idxNext); slice(source, slice); } template class Container /*e.g. QVector*/> void GenericSlicer::previous(const ContainerType &source, Container &slice){ setStartIndex(_idxPrevious); slice(source, slice); } template class Container /*e.g. QVector*/> void GenericSlicer::reset(const ContainerType &source, Container &slice){ setStartIndex(0); slice(source, slice); }