extract explicit mesh with topology information from implicit surfaces with boolean operations, and do surface/volume integrating on them.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

110 lines
4.7 KiB

#include "subface/simple/sphere_face.hpp"
namespace internal
{
auto sphere_face_t::fetch_sdf_evaluator() const -> std::function<double(Eigen::Vector3d)>
{
auto functor = [](Eigen::Vector3d p, Eigen::Vector3d local_to_world_scale, const transform_block& _world_to_local) {
Eigen::Vector4d local_p = _world_to_local * Eigen::Vector4d{p.x(), p.y(), p.z(), 1.0};
const double len = local_p.head<3>().norm();
if (len > std::numeric_limits<double>::epsilon()) {
Eigen::Vector3d normal = local_p.head<3>() / len;
return local_to_world_scale.cwiseProduct(normal).norm() * (len * len - 1);
} else {
return -local_to_world_scale.minCoeff();
}
};
return std::bind(functor, std::placeholders::_1, this->local_to_world_scale(), std::ref(this->raw_world_to_local()));
}
auto sphere_face_t::fetch_sdf_grad_evaluator() const -> std::function<Eigen::Vector3d(Eigen::Vector3d)>
{
auto functor = [](Eigen::Vector3d p, Eigen::Matrix3d trans_world_to_local_linear, const transform_block& _world_to_local) {
Eigen::Vector4d local_p = _world_to_local * Eigen::Vector4d{p.x(), p.y(), p.z(), 1.0};
Eigen::Vector3d normal = local_p.head<3>().normalized();
return trans_world_to_local_linear * normal;
};
return std::bind(functor, std::placeholders::_1, this->trans_world_to_local_linear(), std::ref(this->raw_world_to_local()));
}
auto sphere_face_t::fetch_point_by_param_evaluator() const -> std::function<Eigen::Vector4d(double, double)>
{
auto functor = [](double u, double v, const transform_block& _local_to_world) {
const auto cos_u = std::cos(u);
const auto sin_u = std::sin(u);
const auto cos_v = std::cos(v);
const auto sin_v = std::sin(v);
return _local_to_world * Eigen::Vector4d(cos_u * cos_v, sin_v, sin_u * cos_v, 1.0);
};
return std::bind(functor, std::placeholders::_1, std::placeholders::_2, std::ref(this->raw_local_to_world()));
}
auto sphere_face_t::fetch_param_mapping_evaluator() const -> std::function<Eigen::Vector2d(Eigen::Vector3d)>
{
auto functor = [](Eigen::Vector3d p, const transform_block* _world_to_local) {
Eigen::Vector4d local_p = (*_world_to_local * Eigen::Vector4d{p.x(), p.y(), p.z(), 1.0}).normalized();
const auto u = std::atan2(local_p.z(), local_p.x());
const auto v = std::asin(local_p.y());
return Eigen::Vector2d{u, v};
};
return std::bind(functor, std::placeholders::_1, &this->raw_world_to_local());
}
auto sphere_face_t::fetch_curve_constraint_evaluator(parameter_u_t constraint_var_type, double u) const
-> std::function<constraint_curve_intermediate(double)>
{
const auto cos_u = std::cos(u);
const auto sin_u = std::sin(u);
auto functor = [&](double v, const transform_block& _local_to_world) {
auto cos_v = std::cos(v);
auto sin_v = std::sin(v);
constraint_curve_intermediate res{};
res.f = _local_to_world * Eigen::Vector4d(cos_u * cos_v, sin_v, sin_u * cos_v, 1.0);
res.grad_f = _local_to_world * Eigen::Vector4d(cos_u * -sin_v, cos_v, sin_u * -sin_v, 0.0);
return res;
};
return std::bind(functor, std::placeholders::_1, std::ref(this->raw_local_to_world()));
}
auto sphere_face_t::fetch_curve_constraint_evaluator(parameter_v_t constraint_var_type, double v) const
-> std::function<constraint_curve_intermediate(double)>
{
const auto cos_v = std::cos(v);
const auto sin_v = std::sin(v);
auto functor = [&](double u, const transform_block& _local_to_world) {
auto cos_u = std::cos(u);
auto sin_u = std::sin(u);
constraint_curve_intermediate res{};
res.f = _local_to_world * Eigen::Vector4d(cos_u * cos_v, sin_v, sin_u * cos_v, 1.0);
res.grad_f = _local_to_world * Eigen::Vector4d(-sin_u * cos_v, 0.0, cos_u * cos_v, 0.0);
return res;
};
return std::bind(functor, std::placeholders::_1, std::ref(this->raw_local_to_world()));
}
auto sphere_face_t::fetch_solver_evaluator() const -> std::function<equation_intermediate_t(constraint_curve_intermediate&&)>
{
auto functor = [](constraint_curve_intermediate&& temp_res, const transform_block& _world_to_local) {
implicit_equation_intermediate res{};
Eigen::Vector3d local_f = (_world_to_local * temp_res.f).head<3>();
res.f = local_f.squaredNorm() - 1;
res.df = 2 * local_f.dot((_world_to_local * temp_res.grad_f).head<3>());
return res;
};
return std::bind(functor, std::placeholders::_1, std::ref(this->raw_world_to_local()));
}
} // namespace internal