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