48 #ifndef _SUPER4PCS_ACCELERATORS_INDEXED_NORMAL_HEAL_SET_H_ 49 #define _SUPER4PCS_ACCELERATORS_INDEXED_NORMAL_HEAL_SET_H_ 51 #include "super4pcs/utils/disablewarnings.h" 52 #include "super4pcs/accelerators/utils.h" 71 typedef std::vector<std::vector<unsigned int>>
ChealMap;
74 #define VALIDATE_INDICES true 75 #pragma message "Index validation is enabled in debug mode" 77 #define VALIDATE_INDICES false 83 #undef VALIDATE_INDICES 90 std::vector<ChealMap*> _grid;
93 inline int indexCoordinates(
const Index3D& coord)
const 94 {
return Utils::UnrollIndexLoop<INDEX_VALIDATION_ENABLED>( coord, 2, _egSize ); }
97 inline int indexPos (
const Point& p)
const{
98 return indexCoordinates( coordinatesPos(p) );
102 inline int indexNormal(
const Point& n)
const {
104 vec2pix_ring(_resolution, n.data(), &id);
109 inline Index3D coordinatesPos (
const Point& p)
const 112 .unaryExpr(std::ptr_fun<Point::Scalar,Point::Scalar>(std::floor))
113 .cast<
typename Index3D::Scalar>();
119 : _epsilon(epsilon), _resolution(resolution) {
121 const int gridDepth = -std::log2(epsilon);
122 _egSize = std::pow(2,gridDepth);
124 if (gridDepth <= 0 || !
isValid())
125 throw std::invalid_argument(
126 std::string(
"[IndexedNormalHealSet] Invalid configuration (depth=") +
127 std::to_string(gridDepth) +
128 std::string(
", size=") +
129 std::to_string(_egSize) +
131 _grid = std::vector<ChealMap*> (std::pow(_egSize, 3), NULL);
133 _ngLength = nside2npix(resolution);
135 _epsilon = 1.f/_egSize;
139 for(
unsigned int i = 0; i != _grid.size(); i++)
144 template <
typename Po
intT>
146 const PointT& normal,
150 inline ChealMap*
getMap(
const Point& p) {
151 const int pId = indexPos(p);
152 if (pId == -1)
return NULL;
158 const Index3D pId3 = coordinatesPos(p);
159 const int pId = indexCoordinates(pId3);
160 std::vector<ChealMap*> result;
162 if (pId == -1)
return result;
170 const int lastId = _egSize-1;
171 int imin = pId3[0] == 0 ? 0 : -1;
172 int jmin = pId3[1] == 0 ? 0 : -1;
173 int kmin = pId3[2] == 0 ? 0 : -1;
174 int imax = pId3[0] == lastId ? 1 : 2;
175 int jmax = pId3[1] == lastId ? 1 : 2;
176 int kmax = pId3[2] == lastId ? 1 : 2;
178 for (
int i = imin; i < imax; ++i)
179 for (
int j = jmin; j < jmax; ++j)
180 for (
int k = kmin; k < kmax; ++k)
182 const int id = indexCoordinates(pId3 +
Index3D(i,j,k));
183 ChealMap* g = _grid[id];
192 template <
typename Po
intT>
194 std::vector<unsigned int>&nei);
196 template <
typename Po
intT>
199 std::vector<unsigned int>&nei);
200 template <
typename Po
intT>
205 std::vector<unsigned int>&nei);
219 template <
typename Po
intT>
226 const int pId = indexPos(p.template cast<Scalar>());
227 if (pId == -1)
return false;
229 const int nId = indexNormal(n.template cast<Scalar>());
230 if (nId == -1)
return false;
232 if (_grid[pId] == NULL) _grid[pId] =
new ChealMap(_ngLength);
233 (_grid[pId])->at(nId).push_back(
id);
238 template <
typename Po
intT>
242 std::vector<unsigned int>&nei)
244 using ChealMapIterator = ChealMap::const_iterator;
246 if ( grid == NULL )
return;
248 for(ChealMapIterator it = grid->cbegin();
249 it != grid->cend(); it++){
250 const std::vector<unsigned int>& lnei = *it;
251 nei.insert( nei.end(), lnei.begin(), lnei.end() );
255 template <
typename Po
intT>
260 std::vector<unsigned int>&nei)
263 if ( grid == NULL )
return;
265 const std::vector<unsigned int>& lnei = grid->at(indexNormal(n.template cast<Scalar>()));
266 nei.insert( nei.end(), lnei.begin(), lnei.end() );
270 template <
typename Po
intT>
276 std::vector<unsigned int>&nei)
279 std::vector<ChealMap*> grids =
getEpsilonMaps(p.template cast<Scalar>());
280 if ( grids.empty() )
return;
282 const double alpha = std::acos(cosAlpha);
284 const unsigned int nbSample = std::pow(2,_resolution+1);
285 const double angleStep = double(2) * M_PI / double(nbSample);
288 const double sinAlpha = std::sin(alpha);
290 Eigen::Quaternion<double> q;
291 q.setFromTwoVectors(
Point(0.,0.,1.), n.template cast<Scalar>());
296 typedef std::pair<unsigned int,unsigned int> PairId;
297 std::set< PairId > colored;
298 const int nbgrid = grids.size();
301 for(
unsigned int a = 0; a != nbSample; a++){
302 double theta = double(a) * angleStep;
303 const Point dir = ( q *
Point(sinAlpha*std::cos(theta),
304 sinAlpha*std::sin(theta),
305 cosAlpha ) ).normalized();
306 int id = indexNormal( dir );
308 for (
int i = 0; i != nbgrid; ++i){
309 if(grids[i]->at(
id).size() != 0){
310 colored.emplace(i,
id);
316 for( std::set<PairId>::const_iterator it = colored.cbegin();
317 it != colored.cend(); it++){
318 const std::vector<unsigned int>& lnei = grids[it->first]->at(it->second);
319 nei.insert( nei.end(), lnei.begin(), lnei.end() );
327 #endif // _INDEXED_NORMAL_SET_H_ double Scalar
Definition: normalHealSet.h:68
ChealMap * getMap(const Point &p)
Definition: normalHealSet.h:150
bool isValid() const
Definition: normalHealSet.h:207
bool addElement(const PointT &pos, const PointT &normal, unsigned int id)
Add a new couple pos/normal, and its associated id.
Definition: normalHealSet.h:221
Definition: normalHealSet.h:81
std::vector< ChealMap * > getEpsilonMaps(const Point &p)
Definition: normalHealSet.h:157
IndexedNormalHealSet(double epsilon, int resolution=4)
Definition: normalHealSet.h:118
Eigen::Vector3i Index3D
Definition: normalHealSet.h:70
virtual ~IndexedNormalHealSet()
Definition: normalHealSet.h:138
Work only in 3D, based on healpix.
Definition: normalHealSet.h:66
std::vector< std::vector< unsigned int > > ChealMap
Definition: normalHealSet.h:71
Eigen::Vector3d Point
Definition: normalHealSet.h:69
void getNeighbors(const PointT &p, std::vector< unsigned int > &nei)
Get closest points in euclidean space.
Definition: normalHealSet.h:240