mirror of
https://github.com/allemangD/toddcox-visualize.git
synced 2025-11-10 12:02:47 -05:00
Simplify mesh class
This commit is contained in:
@@ -8,149 +8,75 @@
|
||||
#include <Eigen/Eigen>
|
||||
|
||||
namespace ml {
|
||||
class MeshBase {
|
||||
using Matrix2Xui = Eigen::Matrix<unsigned int, 2, Eigen::Dynamic>;
|
||||
using Matrix3Xui = Eigen::Matrix<unsigned int, 3, Eigen::Dynamic>;
|
||||
using Matrix4Xui = Eigen::Matrix<unsigned int, 4, Eigen::Dynamic>;
|
||||
|
||||
template<typename PT_, typename CT_>
|
||||
class Mesh {
|
||||
public:
|
||||
using PointsType = Eigen::MatrixXf;
|
||||
using CellsType = Eigen::MatrixXi;
|
||||
using Points = PT_;
|
||||
using Cells = CT_;
|
||||
|
||||
[[nodiscard]] virtual Eigen::Index dim() const = 0;
|
||||
Points points;
|
||||
Cells cells;
|
||||
|
||||
[[nodiscard]] virtual PointsType points() const = 0;
|
||||
|
||||
[[nodiscard]] virtual Eigen::Index rank() const = 0;
|
||||
|
||||
[[nodiscard]] virtual CellsType cells() const = 0;
|
||||
Mesh(Points points, Cells cells)
|
||||
: points(std::move(points)), cells(std::move(cells)) {}
|
||||
};
|
||||
|
||||
class DynamicMesh : public MeshBase {
|
||||
PointsType _points;
|
||||
CellsType _cells;
|
||||
|
||||
public:
|
||||
DynamicMesh() = default;
|
||||
|
||||
explicit DynamicMesh(const MeshBase &mesh)
|
||||
: _points(mesh.points()), _cells(mesh.cells()) {}
|
||||
|
||||
DynamicMesh(PointsType points, CellsType cells)
|
||||
: _points(std::move(points)), _cells(std::move(cells)) {}
|
||||
|
||||
Eigen::Index dim() const override {
|
||||
return _points.rows();
|
||||
}
|
||||
|
||||
[[nodiscard]] PointsType &points() {
|
||||
return _points;
|
||||
}
|
||||
|
||||
[[nodiscard]] PointsType points() const override {
|
||||
return _points;
|
||||
}
|
||||
|
||||
Eigen::Index rank() const override {
|
||||
return _points.rows();
|
||||
}
|
||||
|
||||
[[nodiscard]] CellsType &cells() {
|
||||
return _cells;
|
||||
}
|
||||
|
||||
[[nodiscard]] CellsType cells() const override {
|
||||
return _cells;
|
||||
}
|
||||
};
|
||||
|
||||
class CubeMesh : public MeshBase {
|
||||
PointsType::Scalar radius;
|
||||
|
||||
public:
|
||||
explicit CubeMesh(PointsType::Scalar radius = 0.5)
|
||||
: radius(radius) {}
|
||||
|
||||
Eigen::Index dim() const override {
|
||||
return 3;
|
||||
}
|
||||
|
||||
[[nodiscard]] PointsType points() const override {
|
||||
PointsType out(3, 8);
|
||||
out.transpose() <<
|
||||
+radius, +radius, +radius,
|
||||
+radius, +radius, -radius,
|
||||
+radius, -radius, +radius,
|
||||
+radius, -radius, -radius,
|
||||
-radius, +radius, +radius,
|
||||
-radius, +radius, -radius,
|
||||
-radius, -radius, +radius,
|
||||
-radius, -radius, -radius;
|
||||
return out;
|
||||
}
|
||||
|
||||
Eigen::Index rank() const override {
|
||||
return 3;
|
||||
}
|
||||
|
||||
CellsType cells() const override {
|
||||
CellsType out(3, 12);
|
||||
out.transpose() <<
|
||||
0b000, 0b001, 0b010, 0b001, 0b010, 0b011,
|
||||
0b100, 0b101, 0b110, 0b101, 0b110, 0b111,
|
||||
|
||||
0b000, 0b001, 0b100, 0b001, 0b100, 0b101,
|
||||
0b010, 0b011, 0b110, 0b011, 0b110, 0b111,
|
||||
|
||||
0b000, 0b010, 0b100, 0b010, 0b100, 0b110,
|
||||
0b001, 0b011, 0b101, 0b011, 0b101, 0b111;
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
class WireCubeMesh : public MeshBase {
|
||||
PointsType::Scalar radius;
|
||||
long _dim;
|
||||
long _npoints;
|
||||
long _nlines;
|
||||
|
||||
public:
|
||||
explicit WireCubeMesh(long dim = 3, PointsType::Scalar radius = 0.5)
|
||||
: _dim(dim), radius(radius) {
|
||||
_npoints = 1 << _dim;
|
||||
_nlines = _dim * (_npoints >> 1);
|
||||
}
|
||||
|
||||
Eigen::Index dim() const override {
|
||||
return _dim;
|
||||
}
|
||||
|
||||
[[nodiscard]] PointsType points() const override {
|
||||
PointsType out(_dim, _npoints);
|
||||
out.fill(radius);
|
||||
for (int i = 0; i < out.cols(); ++i) {
|
||||
for (int j = 0; j < _dim; ++j) {
|
||||
if ((i >> j) & 1) {
|
||||
out(j, i) *= -1;
|
||||
}
|
||||
auto make_cube(float radius) {
|
||||
Eigen::Matrix3Xf points(3, 8);
|
||||
points.fill(radius);
|
||||
for (int i = 0; i < points.cols(); ++i) {
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
if ((i >> j) & 1) {
|
||||
points(j, i) *= -1;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
Eigen::Index rank() const override {
|
||||
return 2;
|
||||
}
|
||||
Matrix3Xui cells(3, 12);
|
||||
cells.transpose()
|
||||
<< 0b000, 0b001, 0b010, 0b001, 0b010, 0b011,
|
||||
0b100, 0b101, 0b110, 0b101, 0b110, 0b111,
|
||||
|
||||
[[nodiscard]] CellsType cells() const override {
|
||||
CellsType out(2, _nlines);
|
||||
int k = 0;
|
||||
for (int i = 0; i < _npoints; ++i) {
|
||||
for (int j = 0; j < _dim; ++j) {
|
||||
if ((i >> j) & 1) {
|
||||
out(0, k) = i;
|
||||
out(1, k) = i ^ (1 << j);
|
||||
k++;
|
||||
}
|
||||
0b000, 0b001, 0b100, 0b001, 0b100, 0b101,
|
||||
0b010, 0b011, 0b110, 0b011, 0b110, 0b111,
|
||||
|
||||
0b000, 0b010, 0b100, 0b010, 0b100, 0b110,
|
||||
0b001, 0b011, 0b101, 0b011, 0b101, 0b111;
|
||||
|
||||
return Mesh(points, cells);
|
||||
}
|
||||
|
||||
template<size_t Dim>
|
||||
auto make_cube_wire(float radius) {
|
||||
constexpr size_t NPoints = 1 << Dim;
|
||||
constexpr size_t NCells = Dim * (NPoints >> 1);
|
||||
|
||||
Eigen::Matrix<float, Dim, NPoints> points;
|
||||
points.fill(radius);
|
||||
for (int i = 0; i < points.cols(); ++i) {
|
||||
for (int j = 0; j < Dim; ++j) {
|
||||
if ((i >> j) & 1) {
|
||||
points(j, i) *= -1;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
Eigen::Matrix<unsigned int, 2, NCells> cells;
|
||||
int k = 0;
|
||||
for (int i = 0; i < NPoints; ++i) {
|
||||
for (int j = 0; j < Dim; ++j) {
|
||||
if ((i >> j) & 1) {
|
||||
cells(0, k) = i;
|
||||
cells(1, k) = i ^ (1 << j);
|
||||
k++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Mesh(points, cells);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,49 +24,45 @@ namespace Eigen {
|
||||
}
|
||||
|
||||
template<class Derived>
|
||||
void from_json(const nlohmann::json &j, Derived &mat) {
|
||||
void from_json(const nlohmann::json &j, Derived &d) {
|
||||
using Scalar = typename Derived::Scalar;
|
||||
|
||||
auto rows = j["rows"].get<Eigen::Index>();
|
||||
auto cols = j["cols"].get<Eigen::Index>();
|
||||
auto rows = j["rows"].get<Index>();
|
||||
auto cols = j["cols"].get<Index>();
|
||||
auto vals = j["vals"].get<std::vector<Scalar>>();
|
||||
|
||||
mat = Eigen::Map<Derived>(vals.data(), rows, cols);
|
||||
d = Map<Derived>(vals.data(), rows, cols);
|
||||
}
|
||||
}
|
||||
|
||||
namespace nlohmann {
|
||||
template<typename PT_, typename CT_>
|
||||
struct adl_serializer<ml::Mesh<PT_, CT_>> {
|
||||
static void to_json(json &j, const ml::Mesh<PT_, CT_> &m) {
|
||||
j = {
|
||||
{"points", m.points},
|
||||
{"cells", m.cells},
|
||||
};
|
||||
}
|
||||
|
||||
static ml::Mesh<PT_, CT_> from_json(const json &j) {
|
||||
return ml::Mesh<PT_, CT_>(
|
||||
j["points"].get<PT_>(),
|
||||
j["cells"].get<CT_>()
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace ml {
|
||||
static void to_json(nlohmann::json &json, const ml::MeshBase &mesh) {
|
||||
json = {
|
||||
{"points", mesh.points()},
|
||||
{"cells", mesh.cells()},
|
||||
};
|
||||
}
|
||||
|
||||
static void from_json(const nlohmann::json &j, ml::DynamicMesh &mesh) {
|
||||
mesh = {
|
||||
j["points"].get<DynamicMesh::PointsType>(),
|
||||
j["cells"].get<DynamicMesh::CellsType>(),
|
||||
};
|
||||
}
|
||||
|
||||
void write(const ml::MeshBase &mesh, std::ostream &out) {
|
||||
template<typename PT_, typename CT_>
|
||||
void write(const ml::Mesh<PT_, CT_> &mesh, std::ostream &&out) {
|
||||
nlohmann::json json = mesh;
|
||||
nlohmann::json::to_msgpack(json, out);
|
||||
}
|
||||
|
||||
void write(const ml::MeshBase &mesh, const std::string &path) {
|
||||
std::ofstream file(path, std::ios::out | std::ios::binary);
|
||||
write(mesh, file);
|
||||
}
|
||||
|
||||
ml::DynamicMesh read(std::istream &in) {
|
||||
nlohmann::json json = nlohmann::json::from_msgpack(in);
|
||||
return json.get<ml::DynamicMesh>();
|
||||
}
|
||||
|
||||
ml::DynamicMesh read(const std::string &path) {
|
||||
std::ifstream file(path, std::ios::in | std::ios::binary);
|
||||
return read(file);
|
||||
template<typename M_>
|
||||
M_ read(std::istream &&in) {
|
||||
return nlohmann::json::from_msgpack(in).get<M_>();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user