core
Shared MPI block decomposition + asynchronous ghost-layer exchange (header-only C++20)
Loading...
Searching...
No Matches
grid_sdf.hpp
Go to the documentation of this file.
1
9#ifndef PECLET_CORE_GEOM_GRID_SDF_HPP
10#define PECLET_CORE_GEOM_GRID_SDF_HPP
11
12#include <algorithm>
13#include <vector>
14
16
18
23struct GridSdf {
24 std::vector<float> values;
27 Vec<3> spacing{1, 1, 1};
28
30 double at(Index i, Index j, Index k) const {
31 return static_cast<double>(values[i + dims[0] * (j + dims[1] * k)]);
32 }
33
36 double eval(const Vec<3>& p) const {
37 double g[3];
38 Index i0[3], i1[3];
39 double f[3];
40 for (int d = 0; d < 3; ++d) {
41 double c = (p[d] - origin[d]) / spacing[d];
42 c = std::clamp(c, 0.0, static_cast<double>(dims[d] - 1));
43 i0[d] = static_cast<Index>(std::floor(c));
44 i1[d] = std::min<Index>(i0[d] + 1, dims[d] - 1);
45 f[d] = c - static_cast<double>(i0[d]);
46 }
47 double c000 = at(i0[0], i0[1], i0[2]), c100 = at(i1[0], i0[1], i0[2]);
48 double c010 = at(i0[0], i1[1], i0[2]), c110 = at(i1[0], i1[1], i0[2]);
49 double c001 = at(i0[0], i0[1], i1[2]), c101 = at(i1[0], i0[1], i1[2]);
50 double c011 = at(i0[0], i1[1], i1[2]), c111 = at(i1[0], i1[1], i1[2]);
51 double c00 = c000 * (1 - f[0]) + c100 * f[0];
52 double c10 = c010 * (1 - f[0]) + c110 * f[0];
53 double c01 = c001 * (1 - f[0]) + c101 * f[0];
54 double c11 = c011 * (1 - f[0]) + c111 * f[0];
55 double c0 = c00 * (1 - f[1]) + c10 * f[1];
56 double c1 = c01 * (1 - f[1]) + c11 * f[1];
57 return c0 * (1 - f[2]) + c1 * f[2];
58 }
59};
60
62template <typename S>
63GridSdf sample(const S& shape, IVec<3> dims, Vec<3> origin, Vec<3> spacing) {
64 GridSdf g;
65 g.dims = dims;
66 g.origin = origin;
67 g.spacing = spacing;
68 g.values.resize(static_cast<std::size_t>(dims[0]) * dims[1] * dims[2]);
69 for (Index k = 0; k < dims[2]; ++k)
70 for (Index j = 0; j < dims[1]; ++j)
71 for (Index i = 0; i < dims[0]; ++i) {
72 Vec<3> p{origin[0] + i * spacing[0], origin[1] + j * spacing[1],
73 origin[2] + k * spacing[2]};
74 g.values[i + dims[0] * (j + dims[1] * k)] = static_cast<float>(shape.eval(p));
75 }
76 return g;
77}
78
79} // namespace peclet::core::geom
80
81#endif // PECLET_CORE_GEOM_GRID_SDF_HPP
GridSdf sample(const S &shape, IVec< 3 > dims, Vec< 3 > origin, Vec< 3 > spacing)
Sample any analytic SDF onto a grid, producing a GridSdf (e.g. to bake geometry for a solver).
Definition grid_sdf.hpp:63
Kokkos::View< T *, MemSpace > View
1D device array.
Definition view.hpp:26
std::int64_t Index
Signed index type for grids and particles (supersedes block_decomposer's long int IndxT).
Definition types.hpp:15
A signed-distance field sampled on a regular axis-aligned grid (negative inside solid).
Definition grid_sdf.hpp:23
double at(Index i, Index j, Index k) const
Raw sample lookup at integer grid index (i,j,k); no bounds checking.
Definition grid_sdf.hpp:30
Vec< 3 > origin
World position of sample (0,0,0).
Definition grid_sdf.hpp:26
std::vector< float > values
Sample values, x-fastest: idx = i + j*nx + k*nx*ny.
Definition grid_sdf.hpp:24
Vec< 3 > spacing
World-space distance between samples per axis.
Definition grid_sdf.hpp:27
double eval(const Vec< 3 > &p) const
Trilinearly-interpolated signed distance at world point p.
Definition grid_sdf.hpp:36
IVec< 3 > dims
Sample count per axis (nx, ny, nz).
Definition grid_sdf.hpp:25