#pragma once #include namespace internal { // local: cylinder face x^2+y^2-1=0 struct cylinder_face_t final : subface { static constexpr uint64_t max_degree = 2; static constexpr equation_system_type eq_sys_type = equation_system_type::implicit; std::function fetch_sdf_evaluator() const override; std::function fetch_sdf_grad_evaluator() const override; // u: planar angle from x-axis to z-axis // v: depth/height from xz-plane to y-axis std::function fetch_point_by_param_evaluator() const override; std::function fetch_curve_constraint_evaluator(parameter_u_t constraint_var_type, double u) const override; std::function fetch_curve_constraint_evaluator(parameter_v_t constraint_var_type, double v) const override; std::function fetch_solver_evaluator() const override; }; struct cylinder_paired_model_matrix { internal::paired_model_matrix *data{}; }; } // namespace internal namespace detail { template <> struct hasher { size_t operator()(const internal::cylinder_paired_model_matrix &block) const { const auto& mat = block.data->local_to_world.matrix(); // 3x4 Eigen::Matrix3d A = mat.block<3,3>(0,0); Eigen::Vector3d b = mat.col(3); Eigen::Matrix3d B = A.inverse(); Eigen::Matrix R = B.topRows<2>(); Eigen::Matrix3d G = R.transpose() * R; Eigen::Vector2d zero_proj = R * b; size_t h = XXH3_64bits(G.data(), sizeof(Eigen::Matrix3d)); h ^= XXH3_64bits(zero_proj.data(), sizeof(Eigen::Vector2d)); return h; } }; template <> struct default_elem_ctor { internal::cylinder_face_t operator()(const internal::cylinder_paired_model_matrix &k) const { internal::cylinder_face_t res{}; res.model_matrices = const_cast(k.data); return res; } }; } // namespace detail