6 #include <SimpleBVH/BVH.hpp>
14 using namespace simplex;
20 const std::string& output_pos_attr_name)
25 Eigen::AlignedBox<double, Eigen::Dynamic>
bbox(pts_acc.dimension());
27 int64_t box_size =
std::pow(2, pts_acc.dimension());
29 Eigen::MatrixXd pts(vs.size() + (options.
add_box ? box_size : 0), pts_acc.dimension());
32 for (
const auto& v : vs) {
33 pts.row(index) << pts_acc.const_vector_attribute(v).transpose();
34 bbox.extend(pts.row(index).transpose());
39 "Input bbox max {}, min {}, diag {}, potential target edge length: {}",
42 bbox.diagonal().norm(),
46 auto center =
bbox.center();
47 auto r =
bbox.diagonal() / 2.;
52 for (int64_t d = 0; d < box_size; ++d) {
53 std::bitset<32> bits = d;
54 for (int64_t i = 0; i < pts.cols(); ++i) {
55 pts(index, i) = bits[i] == 0 ?
bbox.min()[i] :
bbox.max()[i];
62 const double bbox_diag =
bbox.diagonal().norm();
63 const auto r = Eigen::VectorXd::Ones(pts_acc.dimension()) * bbox_diag;
73 const Eigen::VectorXi res = (
bbox.diagonal() / (bbox_diag * grid_spacing)).cast<
int>() +
74 Eigen::VectorXi::Ones(pts_acc.dimension());
76 Eigen::MatrixXd background_V;
79 if (pts.cols() == 3) {
80 auto v_index = [&res](
int i,
int j,
int k) {
81 return k * (res[0] + 1) * (res[1] + 1) + j * (res[0] + 1) + i;
84 background_V.resize((res[0] + 1) * (res[1] + 1) * (res[2] + 1), 3);
86 for (
int k = 0; k <= res[2]; ++k) {
87 for (
int j = 0; j <= res[1]; ++j) {
88 for (
int i = 0; i <= res[0]; ++i) {
91 background_V.row(v_index(i, j, k)) =
92 bbox.min().array() + ttmp.array() / res.cast<
double>().array();
99 "Grid bbox max {}, min {}, diag {}, potential target edge length: {}",
102 bbox.diagonal().norm(),
113 Eigen::MatrixXd
vertices(dim * facest.size(), pts_acc.dimension());
114 Eigen::MatrixXi
faces(facest.size(), dim);
116 for (
const auto& f : facest) {
122 assert(tmp.size() == dim);
123 for (int64_t j = 0; j < tmp.size(); ++j) {
124 auto p = pts_acc.const_vector_attribute(tmp[j]);
125 faces(findex, j) = count;
136 const double min_dist =
138 : (bbox_diag * bbox_diag * grid_spacing * grid_spacing / 4);
139 std::vector<Eigen::VectorXd> good;
140 SimpleBVH::VectorMax3d nearest_point;
141 for (int64_t i = 0; i < background_V.rows(); ++i) {
143 bvh.nearest_facet(background_V.row(i), nearest_point, sq_dist);
144 if (sq_dist >= min_dist) good.emplace_back(background_V.row(i));
146 int64_t current_size = pts.rows();
147 pts.conservativeResize(current_size + good.size(), pts.cols());
148 for (
const auto& v : good) {
149 pts.row(current_size) = v.transpose();
158 int64_t old_size = pts.rows();
159 auto remove_duplicated_vertices = [](Eigen::MatrixXd& P) -> Eigen::MatrixXd {
160 std::vector<Eigen::VectorXd> vec;
161 for (int64_t i = 0; i < P.rows(); ++i) vec.push_back(P.row(i));
163 std::sort(vec.begin(), vec.end(), [](Eigen::VectorXd
const& p1, Eigen::VectorXd
const& p2) {
164 return (p1(0) < p2(0)) || (p1(0) == p2(0) && p1(1) < p2(1)) ||
165 (p1(0) == p2(0) && p1(1) == p2(1) && p1(2) < p2(2));
168 auto it = std::unique(vec.begin(), vec.end());
169 vec.resize(std::distance(vec.begin(), it));
171 Eigen::MatrixXd new_P(vec.size(), P.cols());
172 for (int64_t i = 0; i < vec.size(); ++i) {
173 new_P.row(i) = vec[i];
180 pts = remove_duplicated_vertices(pts);
181 wmtk::logger().info(
"removed {} duplicated vertices", pts.rows() - old_size);
184 wmtk::logger().info(
"generated {} vertices", pts.rows());
185 std::shared_ptr<PointMesh> pts_mesh = std::make_shared<PointMesh>(pts.rows());
const attribute::Accessor< T, Mesh, D > create_const_accessor(const attribute::MeshAttributeHandle &handle) const
std::vector< Tuple > get_all(PrimitiveType type) const
Generate a vector of Tuples from global vertex/edge/triangle/tetrahedron index.
PrimitiveType top_simplex_type() const
std::shared_ptr< PointMesh > to_points(const Mesh &mesh, const attribute::MeshAttributeHandle &pts_attr, const ToPtsOptions &options, const std::string &output_pos_attr_name)
attribute::MeshAttributeHandle set_matrix_attribute(const Mat &data, const std::string &name, const PrimitiveType &type, Mesh &mesh)
std::vector< Tuple > vertices(const Mesh &m, const Simplex &simplex)
std::vector< Tuple > faces_single_dimension_tuples(const Mesh &mesh, const Simplex &simplex, const PrimitiveType face_type)
SimplexCollection faces(const Mesh &mesh, const Simplex &simplex, const bool sort_and_clean)
Returns all faces of a simplex.
spdlog::logger & logger()
Retrieves the current logger.
Vector< double, 3 > Vector3d
Rational pow(const Rational &x, int p)