11#include <kernel/util/dist.hpp> 
   12#include <kernel/util/dist_file_io.hpp> 
   13#include <kernel/geometry/cgal.hpp> 
   14#include <kernel/geometry/atlas/chart.hpp> 
   24#ifdef FEAT_HAVE_FPARSER 
   40        FileError(filename.empty() ? msg : (filename + 
": " + msg))
 
   69    template<
typename CoordType_, 
int dim_>
 
  133#if defined(FEAT_HAVE_CGAL) || defined(DOXYGEN) 
  141    template<
typename CoordType_>
 
  176        const std::size_t nv = mask.size();
 
  177        for(std::size_t i(0); i < nv; ++i)
 
  180            point[1], point[2]) ? int(!_invert) : int(_invert));
 
  193    template<
typename MeshType>
 
  195      public VoxelMasker<typename MeshType::CoordType, MeshType::shape_dim>
 
  229        const std::size_t nv = mask.size();
 
  230        for(std::size_t i(0); i < nv; ++i)
 
  247    template<
typename Lambda_, 
typename CoordType_, 
int dim_>
 
  269        _lambda(std::forward<Lambda_>(lambda))
 
  282        const std::size_t nv = mask.size();
 
  283        for(std::size_t i(0); i < nv; ++i)
 
  286          mask[i] = (
_lambda(cpt) ? 1 : 0);
 
  291#if defined(FEAT_HAVE_FPARSER) || defined(DOXYGEN) 
  328        _parser.AddConstant(
"pi", Math::pi<double>());
 
  329        _parser.AddConstant(
"eps", Math::eps<double>());
 
  332        if(dim_ > 1) vars += 
",y";
 
  333        if(dim_ > 2) vars += 
",z";
 
  340          msg.append(
"\n>>> '");
 
  357        const std::size_t nv = mask.size();
 
  358        for(std::size_t i(0); i < nv; ++i)
 
  361          mask[i] = (
_parser.Eval(pt.
v) > 0.0 ? 1 : 0);
 
  411      typedef std::uint64_t 
u64;
 
  440        u64 planes_per_block; 
 
  452        return (((num_x + 7ull)/8ull + 15ull) & ~15ull);
 
  465        u64 compress_block_size; 
 
  472          compress_block_size(0u),
 
  481          compress_block_size(cbs),
 
  489        operator bool()
 const 
  491          return filesize > 
u64(0);
 
  523        operator bool()
 const 
  525          return filesize > 
u64(0);
 
  596        XASSERT((dim >= 0) && (dim < 3));
 
  603        XASSERT((dim >= 0) && (dim < 3));
 
  623        this->_out_of_bounds_value = 
value;
 
  643        return Index(this->_num_points.at(
Index(dim)));
 
  660        return Index(this->_num_points[0] * this->_num_points[1] * this->_num_points[2]);
 
  678        return u64(this->_voxel_map.size());
 
  728      template<
typename Coord_, 
int dim_>
 
  759      template<
typename MeshType_>
 
  790      template<
typename Lambda_>
 
  820      template<
typename Lambda_>
 
  948      WriteResult 
write(
const String& filename, 
const u64 compress_block_size = 128u, 
const int compress_level = 9) 
const;
 
  969      WriteResult 
write(std::ostream& os, 
const u64 compress_block_size = 128u, 
const int compress_level = 9) 
const;
 
  995      ReadResult 
read(std::istream& is, 
const String& filename = 
"");
 
 1008        ASSERT((ix < this->
_num_points[0]) || ((this->_num_points[0] == 0u) && (ix == 0u)));
 
 1009        ASSERT((iy < this->
_num_points[1]) || ((this->_num_points[1] == 0u) && (iy == 0u)));
 
 1010        ASSERT((iz < this->
_num_points[2]) || ((this->_num_points[2] == 0u) && (iz == 0u)));
 
 1024      template<
typename Coord_, 
int dim_>
 
 1028        std::array<i64, dim_> ipt;
 
 1029        for(
int i(0); i < dim_; ++i)
 
 1030          ipt[std::size_t(i)] = 
i64(point[i] * Coord_(
unit_size));
 
 1043      template<
typename Coord_, 
int dim_>
 
 1047        std::array<i64, dim_> ipt;
 
 1048        for(
int i(0); i < dim_; ++i)
 
 1049          ipt[std::size_t(i)] = 
i64(point[i] * Coord_(
unit_size));
 
 1069      template<
typename Coord_, 
int dim_>
 
 1073        std::array<u64, dim_> ibox_min, ibox_max;
 
 1074        for(std::size_t i(0); i < std::size_t(dim_); ++i)
 
 1080            if(this->_out_of_bounds_value)
 
 1082            ibox_min[i] = 
u64(0);
 
 1085            ibox_min[i] = 
u64(imin);
 
 1088          if(
i64(this->_num_points[i]) < imax + 1)
 
 1090            if(this->_out_of_bounds_value)
 
 1092            ibox_max[i] = 
i64(this->_num_points[i]) - 1;
 
 1095            ibox_max[i] = 
u64(imax);
 
 1121      template<
typename Coord_, 
int dim_>
 
 1124        std::array<i64, dim_> ibox_min, ibox_max;
 
 1125        for(std::size_t i(0); i < std::size_t(dim_); ++i)
 
 1127          ibox_min[i] = 
i64(box_min[
int(i)] * Coord_(
unit_size));
 
 1128          ibox_max[i] = 
i64(box_max[
int(i)] * Coord_(
unit_size));
 
 1369      bool _check_box(
const std::array<u64, 1>& box_min, 
const std::array<u64, 1>& box_max) 
const;
 
 1379      bool _check_box(
const std::array<u64, 2>& box_min, 
const std::array<u64, 2>& box_max) 
const;
 
 1389      bool _check_box(
const std::array<u64, 3>& box_min, 
const std::array<u64, 3>& box_max) 
const;
 
 1446      Real _sample_box_3d(
i64 px0, 
i64 px1, 
i64 py0, 
i64 py1, 
i64 pz0, 
i64 pz1, 
i64 xidx0, 
i64 xidx1, 
i64 yidx0, 
i64 yidx1, 
i64 zidx0, 
i64 zidx1) 
const;
 
 1456      Real _sample_box(
const std::array<i64, 1>& box_min, 
const std::array<i64, 1>& box_max) 
const;
 
 1466      Real _sample_box(
const std::array<i64, 2>& box_min, 
const std::array<i64, 2>& box_max) 
const;
 
 1476      Real _sample_box(
const std::array<i64, 3>& box_min, 
const std::array<i64, 3>& box_max) 
const;
 
 1509      template<
typename CoordType_>
 
 1512        XASSERTM(
_num_points[1] == 1ull, 
"cannot use a 1D VoxelMasker to create a 2D/3D voxel mask");
 
 1513        XASSERTM(
_num_points[2] == 1ull, 
"cannot use a 1D VoxelMasker to create a 2D/3D voxel mask");
 
 1515        const CoordType_ x_max = CoordType_(_bbox_max[0]) / CoordType_(
unit_size);
 
 1516        std::vector<int> line_mask(this->_num_points[0], 0);
 
 1518        masker.
mask_line(line_mask, x_min, x_max, coords);
 
 1539      template<
typename CoordType_>
 
 1542        XASSERTM(
_num_points[2] == 1ull, 
"cannot use a 2D VoxelMasker to create a 3D voxel mask");
 
 1544        const CoordType_ x_max = CoordType_(_bbox_max[0]) / CoordType_(
unit_size);
 
 1546        const CoordType_ y_max = CoordType_(_bbox_max[1]) / CoordType_(
unit_size);
 
 1547        std::vector<int> line_mask(this->_num_points[0], 0);
 
 1550        for(
u64 i = beg; i < end; ++i)
 
 1552          coords[1] = y_min + (y_max - y_min) * CoordType_(i % this->_num_points[1]) / CoordType_(this->_num_points[1] - 1u);
 
 1553          masker.
mask_line(line_mask, x_min, x_max, coords);
 
 1575      template<
typename CoordType_>
 
 1579        const CoordType_ x_max = CoordType_(_bbox_max[0]) / CoordType_(
unit_size);
 
 1581        const CoordType_ y_max = CoordType_(_bbox_max[1]) / CoordType_(
unit_size);
 
 1583        const CoordType_ z_max = CoordType_(_bbox_max[2]) / CoordType_(
unit_size);
 
 1585        FEAT_PRAGMA_OMP(parallel)
 
 1587          std::vector<int> line_mask(this->_num_points[0], 0);
 
 1590          FEAT_PRAGMA_OMP(
for schedule(dynamic, 16))
 
 1591          for(
u64 i = beg; i < end; ++i)
 
 1594            coords[1] = y_min + (y_max - y_min) * CoordType_(i % this->_num_points[1]) / CoordType_(this->_num_points[1] - 1u);
 
 1595            coords[2] = z_min + (z_max - z_min) * CoordType_(i / this->_num_points[1]) / CoordType_(this->_num_points[2] - 1u);
 
 1596            masker.
mask_line(line_mask, x_min, x_max, coords);
 
 1622      template<
typename CoordType, 
int dim_>
 
 1626        if(comm.
size() <= 1)
 
 1631        else if(
u64(comm.
size()) <= this->_num_lines)
 
 1640          u64 line_count = (this->_num_lines + comm_size - 1u) / comm_size;
 
 1641          std::size_t block_len = this->_stride_line * line_count;
 
 1644          std::size_t vmap_size = block_len;
 
 1646          if(gather_to_all || (comm_rank == 0))
 
 1647            vmap_size *= 
u64(comm_size);
 
 1648          this->_voxel_map.resize(vmap_size, 0u);
 
 1651          u64 line_beg = comm_rank * line_count;
 
 1652          u64 line_end = 
Math::min((comm_rank + 1u) * line_count, this->_num_lines);
 
 1662            comm.
allgather(this->_voxel_map.data(), block_len, this->_voxel_map.data(), block_len);
 
 1664            comm.
gather(this->_voxel_map.data(), block_len, this->_voxel_map.data(), block_len, 0);
 
 1666        else if(this->_num_lines < 
u64(comm.
size()))
 
 1681            u64 line_count = (this->_num_lines + comm_size - 1u) / comm_size;
 
 1682            std::size_t block_len = this->_stride_line * line_count;
 
 1685            std::size_t vmap_size = block_len;
 
 1687            if(gather_to_all || (comm_rank == 0))
 
 1688              vmap_size *= 
u64(comm_size);
 
 1689            this->_voxel_map.resize(vmap_size, 0u);
 
 1692            u64 line_beg = comm_rank * line_count;
 
 1693            u64 line_end = 
Math::min((comm_rank + 1u) * line_count, this->_num_lines);
 
 1702            sub_comm.
gather(this->_voxel_map.data(), block_len, this->_voxel_map.data(), block_len, 0);
 
 1708              this->_voxel_map.resize(this->_stride_line * this->_num_lines, 0u);
 
 1713            comm.
bcast(this->_voxel_map.data(), this->_stride_line * this->_num_lines, 0);
 
 1717        if(comm.
rank() == 0)
 
 1721        comm.
bcast(&this->_coverage, std::size_t(1u), 0);
 
#define ASSERT(expr)
Debug-Assertion macro definition.
#define XASSERT(expr)
Assertion macro definition.
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
void bcast(void *buffer, std::size_t count, const Datatype &datatype, int root) const
Blocking broadcast.
Comm comm_create_range_incl(int count, int first=0, int stride=1) const
Creates a new sub-communicator from a strided range of ranks.
int size() const
Returns the size of this communicator.
void gather(const void *sendbuf, std::size_t sendcount, const Datatype &sendtype, void *recvbuf, std::size_t recvcount, const Datatype &recvtype, int root) const
Blocking gather.
int rank() const
Returns the rank of this process in this communicator.
void allgather(const void *sendbuf, std::size_t sendcount, const Datatype &sendtype, void *recvbuf, std::size_t recvcount, const Datatype &recvtype) const
Blocking gather-to-all.
bool is_null() const
Checks whether this communicator is a null communicator.
Base class for file related errors.
virtual CoordType signed_dist(const WorldPoint &point) const =0
Computes the signed distance of a point to this chart.
Wrapper for the CGAL Library.
bool point_inside(DataType x, DataType y, DataType z) const
Check whether a point is inside the Polyhedron defined at objects' construction.
Voxel masker implementation for CGAL wrapper.
const Geometry::CGALWrapper< CoordType_ > & _cgal_wrapper
a reference to our CGAL wrapper
virtual void mask_line(std::vector< int > &mask, const CoordType x_min, const CoordType x_max, const PointType &point) override
Computes the mask for an entire X-coordinate row.
VoxelCGALMasker(const Geometry::CGALWrapper< CoordType_ > &cgal_wrapper, bool invert)
Constructor.
Voxel masker implementation for chart classes.
CoordType_ CoordType
the coordinate type
Tiny::Vector< CoordType_, dim_ > PointType
the point type
VoxelChartMasker(const Geometry::Atlas::ChartBase< MeshType > &chart, bool invert)
Constructor.
Voxel masker implementation for lambda expression tests.
CoordType_ CoordType
the coordinate type
VoxelLambdaMasker(Lambda_ &&lambda)
Constructor.
Lambda_ _lambda
the lambda expression
virtual void mask_line(std::vector< int > &mask, const CoordType x_min, const CoordType x_max, const PointType &point) override
Computes the mask for an entire X-coordinate row.
helper class for read function result
helper class for write function result
Error class for VoxelMap related file errors.
bool check_box(const Tiny::Vector< Coord_, dim_ > &box_min, const Tiny::Vector< Coord_, dim_ > &box_max) const
Checks the voxel map entries for a given box of voxels.
i64 _map_coord_idx_lower(i64 xyz, std::size_t sdim) const
Maps a unit coordinate to a X-/Y-/Z-index of the lower voxel in the voxel map.
bool _check_point_nearest(const std::array< i64, 1 > &p) const
Checks the nearest voxel map entry for a given 1D point.
static constexpr u64 header_size
size of voxel map header in bytes
Real _sample_box_1d(i64 px0, i64 px1, i64 xidx0, i64 xidx1, i64 yidx=i64(0), i64 zidx=i64(0)) const
Helper function for _sample_box: samples a 1D edge in X line.
void set_out_of_bounds_value(bool value)
Sets the out-of-bounds value for the voxel map.
Real _calc_sample_rate(i64 xyz, i64 idx, std::size_t sdim) const
Helper function for _sample_voxel_map_Xd: compute the sample rate in a given dimension.
std::vector< char > _voxel_map
the actual voxel map; its size may be larger than necessary due to padding
void export_to_bmp(const String &filename_prefix) const
Exports the voxel map to a sequence of monochrome BMP image files.
bool _check_point(i64 xidx, i64 yidx, i64 zidx) const
Helper function for _sample_point: checks a single voxel point value.
Real get_bounding_box_min(int dim) const
Returns the minimum bounding box coordinate for a given dimensions.
bool get_out_of_bounds_value() const
Returns the out-of-bounds value for the voxel map.
WriteResult write(const String &filename, const u64 compress_block_size=128u, const int compress_level=9) const
Writes the voxel map into a file that can later be read in.
void render_to_bmp(const String &filename_prefix, Index width, Index height, Index depth) const
Renders the voxel map to a sequence of gray-scale BMP image files.
void _export_plane_to_bmp(std::ostream &os, u64 plane) const
Exports a single plane of the voxel map to a monochrome BMP image file.
i64 _map_coord_idx_upper(i64 xyz, std::size_t sdim) const
Maps a unit coordinate to a X-/Y-/Z-index of the upper voxel in the voxel map.
Real _sample_point_1d_y(i64 py, i64 xidx, i64 yidx, i64 zidx=i64(0)) const
Helper function for _sample_point: samples a 1D edge in Y-parallel line.
Index get_num_points(int dim) const
Returns the number of points of the voxel map in each dimension.
Real _sample_box_2d(i64 px0, i64 px1, i64 py0, i64 py1, i64 xidx0, i64 xidx1, i64 yidx0, i64 yidx1, i64 zidx=i64(0)) const
Helper function for _sample_box: samples a 2D rectangle in XY plane.
std::array< u64, 3u > _num_points
number of points in each dimension
Real _sample_box_3d(i64 px0, i64 px1, i64 py0, i64 py1, i64 pz0, i64 pz1, i64 xidx0, i64 xidx1, i64 yidx0, i64 yidx1, i64 zidx0, i64 zidx1) const
Helper function for _sample_box: samples a 3D cuboid in XYZ volume.
Real sample_point(const Tiny::Vector< Coord_, dim_ > &point) const
Samples the voxel map entry for a given point by multi-linear interpolation.
void compute_map_from_chart(const Dist::Comm &comm, const Geometry::Atlas::ChartBase< MeshType_ > &chart, bool invert, bool gather_to_all=true)
Creates the voxel map based on a chart by utilizing MPI parallelization.
void _compress_voxel_map_line(const std::vector< int > &mask, const u64 line)
Compresses a voxel map line into the voxel map.
u64 get_stride_line() const
Returns the line stride, i.e. the size of a single X-line in bytes.
Real get_bounding_box_max(int dim) const
Returns the maximum bounding box coordinate for a given dimensions.
Real get_domain_coverage() const
Returns the domain coverage of the voxel map.
u64 _compute_domain_coverage() const
Computes the domain coverage of the voxel map.
void export_plane_to_bmp(const String &filename, Real z_coord) const
Exports a single plane of the voxel map to a monochrome BMP image file.
void compute_map(const Dist::Comm &comm, VoxelMasker< Coord_, dim_ > &masker, bool gather_to_all=true)
Creates the voxel map based on a given masker object by utilizing MPI parallelization.
void _compute_voxel_map_lines(VoxelMasker< CoordType_, 2 > &masker, u64 beg, u64 end, u64 offset)
Computes a range of voxel map lines for a 2D domain.
void _compute_voxel_map(const Dist::Comm &comm, VoxelMasker< CoordType, dim_ > &masker, bool gather_to_all)
Computes the voxel map for the domain.
static constexpr u64 magic_number
voxel map magic number
const std::vector< char > & get_map() const
Returns a reference to the voxel map.
void compute_map_from_lambda_3d(const Dist::Comm &comm, Lambda_ &&lambda, bool gather_to_all=true)
Creates the voxel map based on a 3D lambda expression by utilizing MPI parallelization.
u64 get_stride_plane() const
Returns the plane stride, i.e. the size of a single XY-plane in bytes.
bool check_point(u64 ix, u64 iy=0u, u64 iz=0u) const
Returns the value of a specific voxel point in the voxel map.
Real get_bounding_box_volume() const
Returns the volume of the 1D/2D/3D voxel map bounding box.
u64 _num_planes
number of planes; 2D = 1; 3D = num_points[3]
std::uint64_t u64
unsigned 64-bit integer type
Real _sample_point_1d_z(i64 pz, i64 xidx, i64 yidx, i64 zidx) const
Helper function for _sample_point: samples a 1D edge in Z-parallel line.
Index get_num_voxels() const
Returns the total number of voxels in the voxel map.
void set_resolution(Real max_res)
Sets the resolution for the voxel map, i.e. the maximum voxel size in each dimension.
u64 _stride_line
stride of a single voxel line in X dimension
bool check_point_nearest(const Tiny::Vector< Coord_, dim_ > &point) const
Checks the voxel map entry for a given point.
void compute_map_from_formula_3d(const Dist::Comm &comm, const String &formula, bool gather_to_all=true)
Creates the voxel map based on a 3D formula by utilizing MPI parallelization.
void set_num_points(Index num_x, Index num_y, Index num_z=0u)
Sets the number of points of the voxel map in each dimension.
virtual ~VoxelMap()
virtual destructor
void render_plane_to_bmp(const String &filename, Index width, Index height, Real z_min, Real z_max) const
Renders a plane range of voxel map to a single gray-scale BMP image file.
std::int64_t i64
signed 64-bit integer type
Real sample_box(const Tiny::Vector< Coord_, dim_ > &box_min, const Tiny::Vector< Coord_, dim_ > &box_max) const
Samples the voxel map entries for a given box of voxels.
void _compute_voxel_map_lines(VoxelMasker< CoordType_, 3 > &masker, u64 beg, u64 end, u64 offset)
Computes a range of voxel map lines for a 3D domain.
Real _sample_point_1d_x(i64 px, i64 xidx, i64 yidx=i64(0), i64 zidx=i64(0)) const
Helper function for _sample_point: samples a 1D edge in X-parallel line.
void compute_map_from_off_3d(const Dist::Comm &comm, const String &filename, bool invert, bool gather_to_all=true)
Creates the voxel map based on a 3D OFF model handled by CGAL by utilizing MPI parallelization.
u64 _stride_plane
stride of a single plane in XY dimensions
void _compute_voxel_map_lines(VoxelMasker< CoordType_, 1 > &masker, u64 beg, u64 end, u64 offset)
Computes a range of voxel map lines for a 1D domain.
VoxelMap(const VoxelMap &)=delete
no copies, no problems
void compute_map_from_lambda_2d(const Dist::Comm &comm, Lambda_ &&lambda, bool gather_to_all=true)
Creates the voxel map based on a 2D lambda expression by utilizing MPI parallelization.
u64 _coverage
the coverage of the domain, relative to unit size
void set_bounding_box_2d(Real x_min, Real x_max, Real y_min, Real y_max)
Sets the bounding box for a 2D voxel map.
Real _sample_point_2d(i64 px, i64 py, i64 xidx, i64 yidx, i64 zidx=i64(0)) const
Helper function for _sample_point: samples a 2D square in XY-parallel plane.
static constexpr i64 unit_size
size of a real unit (meter) in our internal units (nanometers)
bool _out_of_bounds_value
the out-of-bounds-value for the voxel map
ReadResult read(const Dist::Comm &comm, const String &filename)
Reads a voxel map from a file.
std::array< i64, 3u > _bbox_min
bounding box dimensions of domain
bool _check_box(const std::array< u64, 1 > &box_min, const std::array< u64, 1 > &box_max) const
Checks whether a 1D box contains at least one active voxel.
void compute_map_from_formula_2d(const Dist::Comm &comm, const String &formula, bool gather_to_all=true)
Creates the voxel map based on a 2D formula by utilizing MPI parallelization.
u64 get_stride_volume() const
Returns the volume stride, i.e. the size of a single XYZ-volume in bytes.
Real _sample_point(const std::array< i64, 1 > &p) const
Samples the voxel map for a given 1D point by multi-linear interpolation.
int _create_stage
current creation stage
u64 _map_coord_idx_nearest(i64 xyz, std::size_t sdim) const
Maps a unit coordinate to a X-/Y-/Z-index of the closest voxel in the voxel map.
VoxelMap()
standard constructor
Real _sample_point_3d(i64 px, i64 py, i64 pz, i64 xidx, i64 yidx, i64 zidx) const
Helper function for _sample_point: samples a 3D cube in XYZ volume.
void set_bounding_box_3d(Real x_min, Real x_max, Real y_min, Real y_max, Real z_min, Real z_max)
Sets the bounding box for a 3D voxel map.
void _render_plane_to_bmp(std::ostream &os, Index width, Index height, i64 box_min_z, i64 box_max_z) const
Renders a plane range of voxel map to a single gray-scale BMP image file.
static u64 calc_line_stride(u64 num_x)
ensure that we're not compiling on some freak architecture...
Real _sample_box(const std::array< i64, 1 > &box_min, const std::array< i64, 1 > &box_max) const
Samples a 1D box of the voxel map.
Real get_domain_volume() const
Returns the covered domain volume.
u64 _num_lines
number of lines; 2D = num_points[2]; 3D: = num_points[2] * num_points[3]
Interface for voxel masker for the VoxelMap class.
CoordType_ CoordType
the coordinate type
static CoordType x_coord(const CoordType x_min, const CoordType x_max, const std::size_t i, const std::size_t n)
Computes the X-coordinate for a given point.
Tiny::Vector< CoordType_, dim_ > PointType
the point type
virtual void mask_line(std::vector< int > &mask, const CoordType x_min, const CoordType x_max, const PointType &point)=0
Computes the mask for an entire X-coordinate row.
virtual ~VoxelMasker()
virtual destructor
Class for parser related errors.
String class implementation.
Tiny Vector class template.
T_ v[s_]
actual vector data
std::uint64_t u64
unsigned 64-bit integer type
@ other
generic/other permutation strategy
std::int64_t i64
signed 64-bit integer type
T_ min(T_ a, T_ b)
Returns the minimum of two values.
double Real
Real data type.
@ value
specifies whether the space should supply basis function values
std::uint64_t Index
Index data type.