21 const std::string& output_pos_attr_name)
26 Eigen::AlignedBox<double, Eigen::Dynamic>
bbox(pts_acc.dimension());
28 int64_t box_size = std::pow(2, pts_acc.dimension());
30 Eigen::MatrixXd pts(vs.size() + (options.
add_box ? box_size : 0), pts_acc.dimension());
33 for (
const auto& v : vs) {
34 pts.row(index) << pts_acc.const_vector_attribute(v).transpose();
35 bbox.extend(pts.row(index).transpose());
40 "Input bbox max {}, min {}, diag {}, potential target edge length: {}",
43 bbox.diagonal().norm(),
47 auto center =
bbox.center();
48 auto r =
bbox.diagonal() / 2.;
53 for (int64_t d = 0; d < box_size; ++d) {
54 std::bitset<32> bits = d;
55 for (int64_t i = 0; i < pts.cols(); ++i) {
56 pts(index, i) = bits[i] == 0 ?
bbox.min()[i] :
bbox.max()[i];
63 const double bbox_diag =
bbox.diagonal().norm();
64 const auto r = Eigen::VectorXd::Ones(pts_acc.dimension()) * bbox_diag;
74 const Eigen::VectorXi res = (
bbox.diagonal() / (bbox_diag * grid_spacing)).cast<
int>() +
75 Eigen::VectorXi::Ones(pts_acc.dimension());
77 Eigen::MatrixXd background_V;
80 if (pts.cols() == 3) {
81 auto v_index = [&res](
int i,
int j,
int k) {
82 return k * (res[0] + 1) * (res[1] + 1) + j * (res[0] + 1) + i;
85 background_V.resize((res[0] + 1) * (res[1] + 1) * (res[2] + 1), 3);
87 for (
int k = 0; k <= res[2]; ++k) {
88 for (
int j = 0; j <= res[1]; ++j) {
89 for (
int i = 0; i <= res[0]; ++i) {
90 const Eigen::Vector3d iii(i, j, k);
91 const Eigen::Vector3d ttmp =
bbox.diagonal().array() * iii.array();
92 background_V.row(v_index(i, j, k)) =
93 bbox.min().array() + ttmp.array() / res.cast<
double>().array();
100 "Grid bbox max {}, min {}, diag {}, potential target edge length: {}",
103 bbox.diagonal().norm(),
114 Eigen::MatrixXd
vertices(dim * facest.size(), pts_acc.dimension());
115 Eigen::MatrixXi
faces(facest.size(), dim);
117 for (
const auto& f : facest) {
123 assert(tmp.size() == dim);
124 for (int64_t j = 0; j < tmp.size(); ++j) {
125 auto p = pts_acc.const_vector_attribute(tmp[j]);
126 faces(findex, j) = count;
137 const double min_dist =
139 : (bbox_diag * bbox_diag * grid_spacing * grid_spacing / 4);
140 std::vector<Eigen::VectorXd> good;
141 SimpleBVH::VectorMax3d nearest_point;
142 for (int64_t i = 0; i < background_V.rows(); ++i) {
144 bvh.nearest_facet(background_V.row(i), nearest_point, sq_dist);
145 if (sq_dist >= min_dist) good.emplace_back(background_V.row(i));
147 int64_t current_size = pts.rows();
148 pts.conservativeResize(current_size + good.size(), pts.cols());
149 for (
const auto& v : good) {
150 pts.row(current_size) = v.transpose();
159 int64_t old_size = pts.rows();
160 auto remove_duplicated_vertices = [](Eigen::MatrixXd& P) -> Eigen::MatrixXd {
161 std::vector<Eigen::VectorXd> vec;
162 for (int64_t i = 0; i < P.rows(); ++i) vec.push_back(P.row(i));
164 std::sort(vec.begin(), vec.end(), [](Eigen::VectorXd
const& p1, Eigen::VectorXd
const& p2) {
165 return (p1(0) < p2(0)) || (p1(0) == p2(0) && p1(1) < p2(1)) ||
166 (p1(0) == p2(0) && p1(1) == p2(1) && p1(2) < p2(2));
169 auto it = std::unique(vec.begin(), vec.end());
170 vec.resize(std::distance(vec.begin(), it));
172 Eigen::MatrixXd new_P(vec.size(), P.cols());
173 for (int64_t i = 0; i < vec.size(); ++i) {
174 new_P.row(i) = vec[i];
181 pts = remove_duplicated_vertices(pts);
182 wmtk::logger().info(
"removed {} duplicated vertices", pts.rows() - old_size);
185 wmtk::logger().info(
"generated {} vertices", pts.rows());
186 std::shared_ptr<PointMesh> pts_mesh = std::make_shared<PointMesh>(pts.rows());