///|/ Copyright (c) Prusa Research 2022 Tomáš Mészáros @tamasmeszaros ///|/ ///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher ///|/ #ifndef POINTGRID_HPP #define POINTGRID_HPP #include #include #include namespace Slic3r { template class PointGrid { Vec3i m_size; std::vector> m_data; const int XY; public: explicit PointGrid(std::vector> data, const Vec3i &size) : m_data(std::move(data)), m_size{size}, XY{m_size.x() * m_size.y()} {} const Vec<3, T> & get(size_t idx) const { return m_data[idx]; } const Vec<3, T> & get(const Vec3i &coord) const { return m_data[get_idx(coord)]; } size_t get_idx(const Vec3i &coord) const { size_t ret = coord.z() * XY + coord.y() * m_size.x() + coord.x(); return ret; } Vec3i get_coord(size_t idx) const { int iz = idx / XY; int iy = (idx / m_size.x()) % m_size.y(); int ix = idx % m_size.x(); return {ix, iy, iz}; } const std::vector> & data() const { return m_data; } size_t point_count() const { return m_data.size(); } bool empty() const { return m_data.empty(); } }; template PointGrid point_grid(Ex policy, const BoundingBox3Base> &bounds, const Vec<3, CoordT> &stride) { Vec3i numpts = Vec3i::Zero(); for (int n = 0; n < 3; ++n) numpts(n) = (bounds.max(n) - bounds.min(n)) / stride(n); std::vector> out(numpts.x() * numpts.y() * numpts.z()); size_t XY = numpts[X] * numpts[Y]; execution::for_each(policy, size_t(0), out.size(), [&](size_t i) { int iz = i / XY; int iy = (i / numpts[X]) % numpts[Y]; int ix = i % numpts[X]; out[i] = Vec<3, CoordT>(ix * stride.x(), iy * stride.y(), iz * stride.z()); }); return PointGrid{std::move(out), numpts}; } } // namespace Slic3r #endif // POINTGRID_HPP