8 changed files with 222 additions and 25 deletions
Binary file not shown.
@ -0,0 +1,8 @@ |
|||
//
|
|||
// Created by cflin on 4/24/23.
|
|||
//
|
|||
|
|||
#include "IrregularMesh.h" |
|||
|
|||
namespace top { |
|||
} // top
|
@ -0,0 +1,137 @@ |
|||
//
|
|||
// Created by cflin on 4/24/23.
|
|||
//
|
|||
|
|||
#ifndef TOP3D_IRREGULARMESH_H |
|||
#define TOP3D_IRREGULARMESH_H |
|||
|
|||
#include "Mesh.h" |
|||
|
|||
namespace top { |
|||
struct ModelMesh { |
|||
Eigen::MatrixX3d points; |
|||
Eigen::MatrixXi surfaces; |
|||
}; |
|||
|
|||
class IrregularMesh : public Mesh { |
|||
public: |
|||
IrregularMesh(const ModelMesh &arbitrary_mesh) : Mesh() { |
|||
// get num_pixels
|
|||
min_point_box_ = arbitrary_mesh.points.colwise().minCoeff(); |
|||
Eigen::Vector3d box_max_point = arbitrary_mesh.points.colwise().maxCoeff(); |
|||
Eigen::Vector3d box_len = box_max_point - min_point_box_; |
|||
const double percentage_of_min_len = 0.20; |
|||
len_pixel_ = box_len.minCoeff() * percentage_of_min_len; |
|||
Eigen::Vector3d d_num_pixels = box_len / len_pixel_; |
|||
Eigen::Vector3i num_pixels(std::ceil(d_num_pixels(0)), std::ceil(d_num_pixels(1)), |
|||
std::ceil(d_num_pixels(2))); |
|||
|
|||
lx_ = num_pixels(0); |
|||
ly_ = num_pixels(1); |
|||
lz_ = num_pixels(2); |
|||
num_node_ = (lx_ + 1) * (ly_ + 1) * (lz_ + 1); |
|||
num_ele_ = lx_ * ly_ * lz_; |
|||
|
|||
ten_ele_coord2ele_id = Tensor3i(lx_, ly_, lz_); |
|||
ten_node_coord2node_id.setConstant(-1); |
|||
ten_node_coord2node_id = Tensor3i(lx_ + 1, ly_ + 1, lz_ + 1); |
|||
ten_node_coord2node_id.setConstant(-1); |
|||
|
|||
auto EvaluateSDF = [](const Eigen::Vector3d point) { |
|||
Eigen::Vector3d center(1, 1, 1); |
|||
double r = 5; |
|||
return r - (point - center).norm(); |
|||
}; |
|||
auto GetWorldCoordByElementIdx = [&](const Eigen::Vector3i &ele_idx) { |
|||
Eigen::Vector3d local_coord = ele_idx.cast<double>(); |
|||
Eigen::Vector3d world_coord = ((local_coord.array() + 0.5) * len_pixel_).matrix() + min_point_box_; |
|||
return world_coord; |
|||
}; |
|||
auto Is_in_model = [&](const Eigen::Vector3i &ele_idx) { |
|||
return EvaluateSDF(GetWorldCoordByElementIdx(ele_idx)) >= 0; |
|||
}; |
|||
|
|||
static const Eigen::MatrixXi delta_coord = (Eigen::MatrixXi(8, 3) << |
|||
0, 0, 0, |
|||
1, 0, 0, |
|||
1, 1, 0, |
|||
0, 1, 0, |
|||
0, 0, 1, |
|||
1, 0, 1, |
|||
1, 1, 1, |
|||
0, 1, 1 |
|||
).finished(); |
|||
// get num_pixel_ && fill pixel id
|
|||
int cnt_pixel = 0; |
|||
for (int k = 0; k < lz_; ++k) { |
|||
for (int j = 0; j < ly_; ++j) { |
|||
for (int i = 0; i < lx_; ++i) { |
|||
if (Is_in_model({i, j, k})) { |
|||
ten_ele_coord2ele_id(i, j, k) = cnt_pixel++; |
|||
for (int di = 0; di < delta_coord.rows(); ++di) { |
|||
Eigen::Vector3i cur_delta_coord = delta_coord.row(di); |
|||
ten_node_coord2node_id(i + cur_delta_coord(0), j + cur_delta_coord(1), |
|||
k + cur_delta_coord(2)) = 1; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
num_pixel_ = cnt_pixel; |
|||
// get_num_node_pixel && fill node_id
|
|||
int cnt_node_pixel = 0; |
|||
for (int k = 0; k < lz_ + 1; ++k) { |
|||
for (int j = 0; j < ly_ + 1; ++j) { |
|||
for (int i = 0; i < lx_ + 1; ++i) { |
|||
if (ten_node_coord2node_id(i, j, k) == 1) { |
|||
ten_node_coord2node_id(i, j, k) = cnt_node_pixel++; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
num_node_pixel_ = cnt_node_pixel; |
|||
// fill mat_ele_id2dofs_
|
|||
mat_ele_id2dofs_.resize(num_pixel_, NUM_NODES_EACH_ELE * 3); |
|||
for (int k = 0; k < lz_; ++k) { |
|||
for (int j = 0; j < ly_; ++j) { |
|||
for (int i = 0; i < lx_; ++i) { |
|||
int cur_ele_id = ten_ele_coord2ele_id(i, j, k); |
|||
if (cur_ele_id == -1) { |
|||
continue; |
|||
} |
|||
Eigen::MatrixXi world_node_coords = delta_coord.rowwise() + Eigen::RowVector3i(i, j, k); |
|||
assert(world_node_coords.rows() == 8 && world_node_coords.cols() == 3); |
|||
Eigen::Vector<int, 8> node_ids = ten_node_coord2node_id(world_node_coords); |
|||
for (int nodi = 0; nodi < 8; ++nodi) { |
|||
mat_ele_id2dofs_(cur_ele_id, {3 * nodi, 3 * nodi + 1, 3 * nodi + 2}) = Eigen::Vector3i( |
|||
3 * node_ids(nodi), 3 * node_ids(nodi) + 1, 3 * node_ids(nodi) + 2); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
int GetNumDofs() const override { |
|||
return num_node_pixel_ * 3; |
|||
} |
|||
|
|||
int GetNumEles() const override { |
|||
return num_pixel_; |
|||
} |
|||
|
|||
int GetNumNodes() const override { |
|||
return num_node_pixel_; |
|||
} |
|||
|
|||
private: |
|||
double len_pixel_; |
|||
double num_pixel_; |
|||
double num_node_pixel_; |
|||
Eigen::Vector3d min_point_box_; |
|||
|
|||
}; |
|||
|
|||
} // top
|
|||
|
|||
#endif //TOP3D_IRREGULARMESH_H
|
Loading…
Reference in new issue