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.

98 lines
4.2 KiB

#include <math/math_defs.hpp>
#include <subface/extrude/extrude_side_face.hpp>
namespace internal
{
double extrude_side_function_impl::eval_sdf(pointer_wrapper<subface> object, Eigen::Vector3d p)
{
Eigen::Vector4d local_p = object->world_to_local * Eigen::Vector4d{p.x(), p.y(), p.z(), 1.0};
extrude_axis* axis_ = reinterpret_cast<extrude_axis*>(object->additional_structure[0]);
const auto v = axis_->get_closest_param(local_p.head<3>());
auto [pattern_p, local_TBN] = axis_->to_pattern_local(v, local_p.head<3>());
pattern* pattern_ = reinterpret_cast<pattern*>(object->additional_structure[1]);
const auto sdf = pattern_->eval_sdf(pattern_p);
return sdf;
}
Eigen::Vector3d extrude_side_function_impl::eval_sdf_grad(pointer_wrapper<subface> object, Eigen::Vector3d p)
{
Eigen::Vector4d local_p = object->world_to_local * Eigen::Vector4d{p.x(), p.y(), p.z(), 1.0};
Eigen::Vector2d normal = local_p.head<2>().normalized();
return object->trans_world_to_local_linear() * Eigen::Vector3d{normal.x(), normal.y(), 0.0};
}
Eigen::Vector2d extrude_side_function_impl::map_point_to_param(pointer_wrapper<subface> object, Eigen::Vector3d p)
{
Eigen::Vector4d local_p = object->world_to_local * Eigen::Vector4d{p.x(), p.y(), p.z(), 1.0};
return Eigen::Vector2d(corrected_atan2(local_p.y(), local_p.x()), local_p.z());
}
std::tuple<Eigen::Vector4d, double, double> extrude_side_function_impl::map_param_to_point_with_weight(
pointer_wrapper<subface> object,
Eigen::Vector2d p)
{
const auto cos_u = std::cos(p.x());
const auto sin_u = std::sin(p.x());
Eigen::Vector4d world_x = object->local_to_world * Eigen::Vector4d(cos_u, sin_u, p.y(), 1.0);
Eigen::Vector4d world_n = (object->local_to_world * Eigen::Vector4d(cos_u, sin_u, .0, .0)).normalized();
auto x_dot_n = world_x.dot(world_n);
const auto local_to_param_jacobi = 1.; // sin_u^2 + cos_u^2 = 1
const auto volume_jacobi = object->local_to_world.linear().determinant();
const auto surface_jacobi =
volume_jacobi * (object->trans_world_to_local_linear() * Eigen::Vector3d(cos_u, sin_u, .0)).norm();
return {world_x, surface_jacobi * local_to_param_jacobi, volume_jacobi * local_to_param_jacobi * x_dot_n};
}
internal::constraint_curve_intermediate extrude_side_function_impl::eval_du_constraint(pointer_wrapper<subface> object,
Eigen::Vector2d p)
{
internal::constraint_curve_intermediate res{};
const auto cos_u = std::cos(p.x());
const auto sin_u = std::sin(p.x());
res.f = object->local_to_world * Eigen::Vector4d(cos_u, sin_u, p.y(), 1.0);
res.grad_f = object->local_to_world * Eigen::Vector4d(-sin_u, cos_u, 0, 0.0);
return res;
}
internal::constraint_curve_intermediate extrude_side_function_impl::eval_dv_constraint(pointer_wrapper<subface> object,
Eigen::Vector2d p)
{
internal::constraint_curve_intermediate res{};
const auto cos_u = std::cos(p.x());
const auto sin_u = std::sin(p.x());
res.f = object->local_to_world * Eigen::Vector4d(cos_u, sin_u, p.y(), 1.0);
res.grad_f = object->local_to_world * Eigen::Vector4d(0, 0, 1, 0.0);
return res;
}
internal::equation_intermediate_t extrude_side_function_impl::eval_intersection(
pointer_wrapper<subface> object,
const internal::constraint_curve_intermediate& res_on_other)
{
internal::implicit_equation_intermediate res{};
Eigen::Vector3d local_f = (object->world_to_local * res_on_other.f).head<3>();
res.f = local_f.head<2>().squaredNorm() - 1;
res.df = 2 * local_f.head<2>().dot((object->world_to_local * res_on_other.grad_f).head<2>());
return res;
}
std::array<internal::periodical_state_t, 2> extrude_side_function_impl::decide_periodical_state(pointer_wrapper<subface> object,
Eigen::Vector4d local_p)
{
return {common_decide_periodical_state(local_p), periodical_state_t::invalid};
}
} // namespace internal