#pragma once #include namespace internal { // local: plane x=0 struct plane_t final : subface { static constexpr uint64_t max_degree = 1; 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 local x-axis // v: planar local 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 plane_paired_model_matrix { internal::paired_model_matrix *data{}; }; } // namespace internal namespace detail { template <> struct hasher { size_t operator()(const internal::plane_paired_model_matrix &block) const { const auto& mat = block.data->local_to_world.matrix(); Eigen::Vector3d n_vec = mat.col(0); double tz = mat.col(3).transpose().dot(n_vec); double norm = n_vec.norm(); if (norm < 1e-8) { n_vec = Eigen::Vector3d::UnitZ(); norm = 1.0; } else { n_vec /= norm; } double d = -tz / norm; // 平面方程: n·x = d // 可选:统一法向方向(例如让 z 分量优先为正) if (n_vec[2] < -1e-8 || (std::abs(n_vec[2]) < 1e-8 && (n_vec[1] < -1e-8 || (std::abs(n_vec[1]) < 1e-8 && n_vec[0] < 0)))) { n_vec = -n_vec; d = -d; } Eigen::Vector4d hash_key; hash_key << n_vec, d; return XXH3_64bits(hash_key.data(), sizeof(Eigen::Vector4d)); } }; template <> struct default_elem_ctor { internal::plane_t operator()(const internal::plane_paired_model_matrix &k) const { internal::plane_t res{}; res.model_matrices = const_cast(k.data); return res; } }; } // namespace detail