#include #include namespace internal { double extrude_side_function_impl::eval_sdf(pointer_wrapper 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(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(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 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 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 extrude_side_function_impl::map_param_to_point_with_weight( pointer_wrapper 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 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 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 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 extrude_side_function_impl::decide_periodical_state(pointer_wrapper object, Eigen::Vector4d local_p) { return {common_decide_periodical_state(local_p), periodical_state_t::invalid}; } } // namespace internal