1 #ifndef MEDUSA_BITS_DOMAINS_GENERALSURFACEFILL_HPP_
2 #define MEDUSA_BITS_DOMAINS_GENERALSURFACEFILL_HPP_
22 template <
typename vec_t,
typename param_vec_t>
23 GeneralSurfaceFill<vec_t, param_vec_t>::GeneralSurfaceFill() : seed_(
get_seed()) {}
25 template <
typename vec_t,
typename param_vec_t>
26 template <
typename param_func_t,
typename jm_func_t,
typename spacing_func_t>
29 const jm_func_t& param_jacobian,
const spacing_func_t& spacing_function,
int type)
const {
31 "Domain must contain all points corresponding to the parameters in the "
32 "parametric domain. ");
34 operator()(domain, param_domain, param_function, param_jacobian, spacing_function, tree, type);
36 template <
typename vec_t,
typename param_vec_t>
37 template <
typename param_func_t,
typename jm_func_t,
typename spacing_func_t>
40 const jm_func_t& param_jacobian,
const spacing_func_t& spacing_function,
int type)
const {
42 operator()(domain, param_domain, param_function, param_jacobian, spacing_function, type);
45 template <
typename vec_t,
typename param_vec_t>
46 template <
typename param_func_t,
typename jm_func_t,
typename search_t,
typename spacing_func_t>
49 const jm_func_t& param_jacobian,
const spacing_func_t& spacing_function, search_t& tree,
51 auto param = [¶m_function, ¶m_jacobian](param_vec_t t) {
52 return std::make_pair(param_function(t), param_jacobian(t));
54 fillParametrization(domain, param_domain, param, spacing_function, tree, type);
57 template <
typename vec_t,
typename param_vec_t>
58 template <
typename param_func_t,
typename search_t,
typename spacing_func_t>
61 const spacing_func_t& spacing_function, search_t& tree,
int type)
const {
62 if (type == 0) type = -1;
63 std::mt19937 gen(seed_);
68 int end_node = param_domain.
size();
71 "Parametric domain shape must have `contains` method implemented if empty "
72 "parametric domain is given. Try supplying an initial point.");
74 param_vec_t lo_bound, hi_bound, random_node;
75 std::tie(lo_bound, hi_bound) = param_domain.
shape().bbox();
76 std::vector<std::uniform_real_distribution<scalar_t>> distributions;
77 for (
int j = 0; j < param_dim; ++j) distributions.emplace_back(lo_bound[j], hi_bound[j]);
81 Eigen::Matrix<scalar_t, dim, param_dim> jm;
83 for (
int j = 0; j < param_dim; ++j) { random_node[j] = distributions[j](gen); }
85 std::tie(point, jm) = param(random_node);
86 check_radius = spacing_function(point);
87 d_sq = tree.size() == 0 ? 10 * check_radius * check_radius :
88 tree.query(point).second[0];
89 if (++count >= 10000) {
90 std::string message =
"No suitable node in parametric domain could be found after "
91 "10000 tries. This might happen if parametric domain volume "
92 "is very small compared to the volume of the bounding box or"
93 " if there are a lot of nodes in input domain.";
94 throw std::runtime_error(message);
96 }
while (!param_domain.
contains(random_node, param_boundary_search) ||
97 !(d_sq >= (zeta * check_radius) * (zeta * check_radius)));
106 while (cur_node < end_node && end_node < max_points) {
107 param_vec_t param_point = param_domain.
pos(cur_node);
109 Eigen::Matrix<scalar_t, dim, param_dim> jm;
110 std::tie(initial_pt, jm) = param(param_point);
116 for (
const auto& u_cand : unit_candidates) {
117 scalar_t alpha = spacing_function(initial_pt) / (jm * u_cand).norm();
118 param_vec_t node = param_point + alpha * u_cand;
119 if (!param_domain.
contains(node, param_boundary_search))
continue;
122 Eigen::Matrix<scalar_t, dim, param_dim> new_jm;
123 std::tie(new_pt, new_jm) = param(node);
125 scalar_t d_sq = tree.query(new_pt).second[0];
127 scalar_t check_radius = (new_pt - initial_pt).norm();
129 if (d_sq < (zeta * check_radius) * (zeta * check_radius))
continue;
143 if (end_node >= max_points) {
144 std::cerr <<
"Maximum number of points reached, fill may be incomplete." << std::endl;
148 template <
typename vec_t,
typename param_vec_t>
151 assert_msg((0 < zeta && zeta < 1),
"Zeta must be between 0 and 1, got %f.", zeta);
157 #endif // MEDUSA_BITS_DOMAINS_GENERALSURFACEFILL_HPP_