#include <Eigen/Dense>
#include <cmath>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
namespace
{
{
{
+ message);
}
}
{
}
Reader create_reader()
{
}
Writer create_writer()
{
}
{
static_cast<ptrdiff_t>(matrix.outerStride() * sizeof(double));
static_cast<ptrdiff_t>(matrix.innerStride() * sizeof(double));
return layout;
}
{
Eigen::MatrixXd heights(
return heights;
}
struct Plane
{
double offset;
double slope_x;
double slope_y;
};
Plane fit_plane(const Eigen::MatrixXd &heights)
{
const Eigen::Index count = (heights.array() == heights.array()).count();
Eigen::MatrixXd design(count, 3);
Eigen::VectorXd z(count);
Eigen::Index row = 0;
const Eigen::Index columns = heights.cols();
const Eigen::Index rows = heights.rows();
for (Eigen::Index x = 0; x < columns; ++x)
{
const double point_x = static_cast<double>(x);
for (Eigen::Index y = 0; y < rows; ++y)
{
if (!std::isnan(heights(y, x)))
{
design.row(row) << 1.0, point_x, static_cast<double>(y);
z(row++) = heights(y, x);
}
}
}
const Eigen::Vector3d solution = design.colPivHouseholderQr().solve(z);
return {solution(0), solution(1), solution(2)};
}
void remove_plane(Eigen::MatrixXd &heights, const Plane &plane)
{
const Eigen::Index columns = heights.cols();
const Eigen::Index rows = heights.rows();
for (Eigen::Index x = 0; x < columns; ++x)
{
const double column_offset =
plane.offset + plane.slope_x * static_cast<double>(x);
for (Eigen::Index y = 0; y < rows; ++y)
{
heights(y, x) -=
column_offset + plane.slope_y * static_cast<double>(y);
}
}
}
void write_matrix(
const char *path,
const sdfio_header *source,
const Eigen::MatrixXd &heights)
{
Header header = copy_header(source);
Writer writer = create_writer();
}
}
int main(int argc, char **argv)
{
if (argc < 3)
{
std::cerr << "usage: " << argv[0] << " input.sdf output.sdf\n";
return 1;
}
const char *input = argv[1];
const char *output = argv[2];
try
{
Reader reader = create_reader();
Eigen::MatrixXd heights = read_matrix(reader.get());
remove_plane(heights, fit_plane(heights));
}
catch (const std::exception &error)
{
std::cerr << error.what() << "\n";
return 1;
}
}
Files by path, and the stream over a C file.
sdfio_status sdfio_open_file(sdfio_reader *reader, const char *path)
Opens the file at a path as the source and reads its header, as sdfio_open_stream() does for a stream...
sdfio_status sdfio_create_file(sdfio_writer *writer, const char *path, const sdfio_header *header)
Creates the file at a path and starts it as sdfio_create_stream() does.
const sdfio_layout * sdfio_layout_packed(sdfio_data_type type)
Returns the layout of a plain array: the elements follow each other and the rows follow each other.
sdfio_status sdfio_reader_add_binary(sdfio_reader *reader)
Adds the binary format to the formats that the reader reads, the version numbers bISO-1....
const sdfio_header * sdfio_reader_header(const sdfio_reader *reader)
Returns the header of the opened file, or null if no file is open.
struct sdfio_reader sdfio_reader
Opaque handle of a reader.
Definition reader.h:58
sdfio_status sdfio_reader_add_ascii(sdfio_reader *reader)
Adds the ASCII format to the formats that the reader reads, the version numbers aISO-1....
sdfio_status sdfio_reader_create(const sdfio_allocator *allocator, sdfio_reader **reader)
Creates a reader.
sdfio_status sdfio_read_heights(sdfio_reader *reader, const sdfio_layout *layout, void *dst)
Reads the remaining rows as heights in metres into a buffer that lies in memory as the layout describ...
const char * sdfio_reader_error_message(const sdfio_reader *reader)
Returns a description of the most recent failure of the reader, or an empty string if none occurred.
void sdfio_reader_free(sdfio_reader *reader)
Releases a reader and closes the file that sdfio_open_file() opened, if any.
Reading and writing of ISO 25178-71 SDF surface data files.
Description of a buffer of the caller for heights or for the values of the data area: the type of its...
Definition layout.h:45
ptrdiff_t element_stride
Distance in bytes between consecutive elements within a row.
Definition layout.h:54
ptrdiff_t row_stride
Distance in bytes between consecutive rows.
Definition layout.h:62
const char * sdfio_status_string(sdfio_status status)
Returns a constant description of a status.
@ SDFIO_BINARY
Binary format.
Definition types.h:83
sdfio_status
Result of a function call.
Definition types.h:31
@ SDFIO_OK
The call succeeded.
Definition types.h:33
const sdfio_allocator * sdfio_default_allocator(void)
Returns the allocator that uses malloc() and free().
@ SDFIO_TYPE_DOUBLE
double: IEEE 754 binary64.
Definition types.h:122
@ SDFIO_TYPE_FLOAT
float: IEEE 754 binary32.
Definition types.h:114
sdfio_status sdfio_writer_add_binary(sdfio_writer *writer)
Adds the binary format to the formats that the writer writes.
sdfio_status sdfio_writer_create(const sdfio_allocator *allocator, sdfio_writer **writer)
Creates a writer.
struct sdfio_writer sdfio_writer
Opaque handle of a writer.
Definition writer.h:69
const char * sdfio_writer_error_message(const sdfio_writer *writer)
Returns a description of the most recent failure of the writer, or an empty string if none occurred.
void sdfio_writer_free(sdfio_writer *writer)
Releases a writer.
sdfio_status sdfio_write_heights(sdfio_writer *writer, const sdfio_layout *layout, const void *src)
Writes the whole data area from a matrix of heights in metres that lies in memory as the layout descr...
sdfio_status sdfio_end_file(sdfio_writer *writer)
Ends the file: closes the trailer, the last record, flushes the stream and, for a file that sdfio_cre...