9#ifndef PECLET_CORE_GEOM_VTI_IO_HPP
10#define PECLET_CORE_GEOM_VTI_IO_HPP
25 std::ofstream
f(
path);
27 throw std::runtime_error(
"writeVti: cannot open " +
path);
29 f <<
"<?xml version=\"1.0\"?>\n"
30 <<
"<VTKFile type=\"ImageData\" version=\"1.0\" byte_order=\"LittleEndian\">\n"
31 <<
" <ImageData WholeExtent=\"0 " <<
nx - 1 <<
" 0 " <<
ny - 1 <<
" 0 " <<
nz - 1 <<
"\""
34 <<
" <Piece Extent=\"0 " <<
nx - 1 <<
" 0 " <<
ny - 1 <<
" 0 " <<
nz - 1 <<
"\">\n"
35 <<
" <PointData Scalars=\"" <<
name <<
"\">\n"
36 <<
" <DataArray type=\"Float32\" Name=\"" <<
name <<
"\" format=\"ascii\">\n";
37 f.setf(std::ios::scientific);
39 for (std::size_t
i = 0;
i < g.
values.size(); ++
i) {
40 f << g.
values[
i] << (((
i + 1) %
static_cast<std::size_t
>(
nx) == 0) ?
'\n' :
' ');
42 f <<
"\n </DataArray>\n </PointData>\n </Piece>\n </ImageData>\n</VTKFile>\n";
46inline std::string
vtiAttr(
const std::string&
s,
const std::string&
key) {
49 if (p == std::string::npos)
50 throw std::runtime_error(
"readVti: missing attribute " +
key);
52 auto e =
s.find(
'"', p);
53 return s.substr(p,
e - p);
59 std::ifstream
f(
path);
61 throw std::runtime_error(
"readVti: cannot open " +
path);
62 std::stringstream
buf;
64 const std::string
s =
buf.str();
73 auto da =
s.find(
"<DataArray");
74 if (
da == std::string::npos)
75 throw std::runtime_error(
"readVti: no DataArray");
80 std::size_t n =
static_cast<std::size_t
>(g.
dims[0]) * g.
dims[1] * g.
dims[2];
82 for (std::size_t
i = 0;
i < n; ++
i) {
100 const std::string&
name =
"vector") {
101 std::ofstream
f(
path);
103 throw std::runtime_error(
"writeVtiVector: cannot open " +
path);
105 f <<
"<?xml version=\"1.0\"?>\n"
106 <<
"<VTKFile type=\"ImageData\" version=\"1.0\" byte_order=\"LittleEndian\">\n"
107 <<
" <ImageData WholeExtent=\"0 " <<
nx - 1 <<
" 0 " <<
ny - 1 <<
" 0 " <<
nz - 1 <<
"\""
110 <<
" <Piece Extent=\"0 " <<
nx - 1 <<
" 0 " <<
ny - 1 <<
" 0 " <<
nz - 1 <<
"\">\n"
111 <<
" <PointData Vectors=\"" <<
name <<
"\">\n"
112 <<
" <DataArray type=\"Float32\" Name=\"" <<
name
113 <<
"\" NumberOfComponents=\"3\" format=\"ascii\">\n";
114 f.setf(std::ios::scientific);
116 std::size_t
npts =
static_cast<std::size_t
>(
nx) *
ny *
nz;
117 for (std::size_t p = 0; p <
npts; ++p) {
120 f <<
" </DataArray>\n </PointData>\n </Piece>\n </ImageData>\n</VTKFile>\n";
125 std::ifstream
f(
path);
127 throw std::runtime_error(
"readVtiVector: cannot open " +
path);
128 std::stringstream
buf;
130 const std::string
s =
buf.str();
139 auto da =
s.find(
"<DataArray");
143 std::size_t
n3 = 3u *
static_cast<std::size_t
>(g.
dims[0]) * g.
dims[1] * g.
dims[2];
145 for (std::size_t
i = 0;
i <
n3; ++
i) {
Sampled (grid) signed-distance field with trilinear interpolation.
std::string vtiAttr(const std::string &s, const std::string &key)
VtiVector readVtiVector(const std::string &path)
Read a vector-field VTI written by writeVtiVector.
GridSdf readVti(const std::string &path)
Read a VTK ImageData (.vti) written by writeVti (ASCII PointData scalar) into a GridSdf.
void writeVti(const std::string &path, const GridSdf &g, const std::string &name="sdf")
Write a GridSdf as a VTK ImageData (.vti), PointData Float32 scalar, ASCII.
void writeVtiVector(const std::string &path, const VtiVector &g, const std::string &name="vector")
Write a 3-component vector field as a VTK ImageData PointData vector (ASCII), ParaView-openable.
Kokkos::View< T *, MemSpace > View
1D device array.
std::int64_t Index
Signed index type for grids and particles (supersedes block_decomposer's long int IndxT).
A signed-distance field sampled on a regular axis-aligned grid (negative inside solid).
Vec< 3 > origin
World position of sample (0,0,0).
std::vector< float > values
Sample values, x-fastest: idx = i + j*nx + k*nx*ny.
Vec< 3 > spacing
World-space distance between samples per axis.
IVec< 3 > dims
Sample count per axis (nx, ny, nz).
A sampled vector field on a regular grid (3 interleaved components per point, x-fastest).
std::vector< float > values