Program Listing for File HashGrid.hpp

Return to documentation for file (include/lvr2/reconstruction/HashGrid.hpp)

/*
 * HashGrid.hpp
 *
 *  Created on: Nov 27, 2014
 *      Author: twiemann
 */

#ifndef HASHGRID
#define HASHGRID

#include <unordered_map>
#include <vector>
#include <string>

#include "QueryPoint.hpp"

#include "lvr2/geometry/BoundingBox.hpp"
#include "lvr2/reconstruction/QueryPoint.hpp"

#include "lvr2/types/PointBuffer.hpp"
#include "lvr2/types/MatrixTypes.hpp"


namespace lvr2
{

class GridBase
{
public:

    GridBase(bool extrude = true) : m_extrude(extrude) {}

    virtual ~GridBase() {}

    virtual void addLatticePoint(int i, int j, int k, float distance = 0.0) = 0;

    virtual void saveGrid(std::string file) = 0;

    /***
     * @brief   Is extrude is set to true, additional cells within the
     *          grid will be create to fill up holes consisting of single
     *          cells.
     *
     * @param extrude   If set to true, additional cells will be created.
     *                  Default value is true.
     */
    virtual void setExtrusion(bool extrude) { m_extrude = extrude; }

protected:
    bool m_extrude;
};

template<typename BaseVecT, typename BoxT>
class HashGrid : public GridBase
{
public:
    typedef std::unordered_map<Vector3i, BoxT*> box_map;

    typedef std::vector<QueryPoint<BaseVecT>*> qp_list;

    typedef typename box_map::iterator box_map_it;

    typedef typename qp_list::iterator query_point_it;

    HashGrid(float resolution, BoundingBox<BaseVecT> bb, bool isVoxelsize = true, bool extrude = true);

    HashGrid(std::string file, const BoundingBox<BaseVecT>& boundingBox, float voxelsize)
        : HashGrid({ file }, boundingBox, voxelsize)
    { }

    HashGrid(const std::vector<std::string>& files, const BoundingBox<BaseVecT>& boundingBox, float voxelsize)
        : HashGrid(files, {}, boundingBox, voxelsize)
    { }

    HashGrid(const std::vector<string>& files,
             const std::vector<BoundingBox<BaseVecT>>& innerBoxes,
             const BoundingBox<BaseVecT>& boundingBox,
             float voxelsize);

    HashGrid(PointBufferPtr src, const BoundingBox<BaseVecT>& boundingBox, float voxelsize)
        : HashGrid({ src }, {}, boundingBox, voxelsize)
    { }

    HashGrid(const std::vector<PointBufferPtr>& chunks,
             const std::vector<BoundingBox<BaseVecT>>& innerBoxes,
             const BoundingBox<BaseVecT>& boundingBox,
             float voxelsize);

    PointBufferPtr toPointBuffer() const;

    void addLatticePoint(int i, int j, int k, float distance = 0.0) override;

    void addLatticePoints(const std::unordered_set<Vector3i>& indices);

    void saveGrid(std::string file) override;

    /***
     * @brief   Returns the number of generated cells.
     */
    size_t getNumberOfCells() const { return m_cells.size(); }

    box_map_it  firstCell() { return m_cells.begin(); }

    box_map_it  lastCell() { return m_cells.end(); }

    query_point_it firstQueryPoint() { return m_queryPoints.begin(); }

    /***
     * @return  Returns an iterator to the last query point
     */
    query_point_it lastQueryPoint() { return m_queryPoints.end(); }

    std::vector<QueryPoint<BaseVecT>>& getQueryPoints() { return m_queryPoints; }
    const std::vector<QueryPoint<BaseVecT>>& getQueryPoints() const { return m_queryPoints; }

    box_map& getCells() { return m_cells; }
    const box_map& getCells() const { return m_cells; }

    /***
     * @brief   Destructor
     */
    virtual ~HashGrid();

    void setBB(BoundingBox<BaseVecT>& bb) { m_boundingBox = bb; }

    BoundingBox<BaseVecT>& getBoundingBox() { return m_boundingBox; }
    const BoundingBox<BaseVecT>& getBoundingBox() const { return m_boundingBox; }

    uint findQueryPoint(int position, const Vector3i& index) const;

    void calcIndex(const BaseVecT& vec, Vector3i& index) const
    {
        index.x() = std::floor(vec.x / m_voxelsize);
        index.y() = std::floor(vec.y / m_voxelsize);
        index.z() = std::floor(vec.z / m_voxelsize);
    }
    Vector3i calcIndex(const BaseVecT& vec) const
    {
        Vector3i ret;
        calcIndex(vec, ret);
        return ret;
    }

    void indexToCenter(const Vector3i& index, BaseVecT& center) const
    {
        center.x = (index.x() + 0.5f) * m_voxelsize;
        center.y = (index.y() + 0.5f) * m_voxelsize;
        center.z = (index.z() + 0.5f) * m_voxelsize;
    }
    BaseVecT indexToCenter(const Vector3i& index) const
    {
        BaseVecT ret;
        indexToCenter(index, ret);
        return ret;
    }

protected:
    void fillNeighbors();

    BoxT* addBox(const Vector3i& index, const BaseVecT& center, float* distances);
    BoxT* addBox(const BaseVecT& center, float* distances)
    {
        return addBox(calcIndex(center), center, distances);
    }
    BoxT* addBox(const Vector3i& index, float* distances)
    {
        return addBox(index, indexToCenter(index), distances);
    }

    box_map m_cells;

    float m_voxelsize;

    std::vector<QueryPoint<BaseVecT>> m_queryPoints;

    BoundingBox<BaseVecT> m_boundingBox;
};

} /* namespace lvr */

#include "HashGrid.tcc"

#endif // HASHGRID