Simplify mesh class

This commit is contained in:
David Allemang
2022-02-16 22:19:03 -05:00
parent 89b9780f6c
commit 22976a9778
6 changed files with 139 additions and 237 deletions

View File

@@ -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);
}
}