Program Listing for File PoissonDiskSampling.h

Return to documentation for file (SPlisHSPlasH/Utilities/PoissonDiskSampling.h)

#ifndef PoissonDiskSampling_H
#define PoissonDiskSampling_H

#include "../Common.h"

#include <random>
#include <unordered_map>
#include <string>

namespace SPH
{
    class PoissonDiskSampling
    {
        typedef Eigen::Matrix<int, 3, 1, Eigen::DontAlign> CellPos;

        struct CellPosHasher
        {
            std::size_t operator()(const CellPos& k) const
            {
                const int p1 = 73856093 * k[0];
                const int p2 = 19349663 * k[1];
                const int p3 = 83492791 * k[2];
                return (size_t)(p1 + p2 + p3);
            }
        };
    public:
        PoissonDiskSampling();

        struct InitialPointInfo
        {
            CellPos cP;
            Vector3r pos;
            unsigned int ID;
        };

        struct HashEntry
        {
            HashEntry() { startIndex = 0; };
            std::vector<unsigned int> samples;
            unsigned int startIndex;
        };

        FORCE_INLINE static int floor(const Real v)
        {
            return (int)(v + 32768.f) - 32768;          // Shift to get positive values
        }

        void sampleMesh(const unsigned int numVertices, const Vector3r *vertices, const unsigned int numFaces, const unsigned int *faces,
            const Real minRadius, const unsigned int numTrials,
            unsigned int distanceNorm, std::vector<Vector3r> &samples);

    private:
        Real m_r;
        unsigned int m_numTrials;
        unsigned int m_numTestpointsPerFace;
        unsigned int m_distanceNorm;
        std::vector<Vector3r> m_faceNormals;
        std::vector<Real> m_areas;
        Real m_totalArea;

        Real m_cellSize;
        Vector3r m_minVec;
        Vector3r m_maxVec;

        std::vector<InitialPointInfo> m_initialInfoVec;
        std::vector<std::vector<CellPos>> m_phaseGroups;

        Real m_maxArea;

        void computeFaceNormals(const unsigned int numVertices, const Vector3r *vertices, const unsigned int numFaces, const unsigned int *faces);
        void determineTriangleAreas(const unsigned int numVertices, const Vector3r *vertices, const unsigned int numFaces, const unsigned int *faces);
        void generateInitialPointSet(const unsigned int numVertices, const Vector3r *vertices, const unsigned int numFaces, const unsigned int *faces);
        unsigned int getAreaIndex(const std::vector<Real>& areas, const Real totalArea, std::default_random_engine &generator, std::uniform_real_distribution<Real> &distribution);
        void parallelUniformSurfaceSampling(std::vector<Vector3r> &samples);

        void quickSort(int left, int right);
        int partition(int left, int right);
        bool compareCellID(CellPos& a, CellPos& b);

        void determineMinX(const unsigned int numVertices, const Vector3r *vertices);

        bool nbhConflict(const std::unordered_map<CellPos, HashEntry, CellPosHasher>& kvMap, const InitialPointInfo& iPI);
        bool checkCell(const std::unordered_map<CellPos, HashEntry, CellPosHasher>& kvMap, const CellPos& cell, const InitialPointInfo& iPI);


    };
}

#endif // PoissonDiskSampling_H