#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_param_mapping_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; }; } // namespace internal namespace detail { struct plane_surface_tag { }; template <> struct tagged_hasher { // TODO: only plane surface should have sign problem size_t operator()(const internal::paired_model_matrix &block) const { const auto &mat = block.local_to_world.matrix(); Eigen::Vector3d normal = mat.col(1).cross(mat.col(2)).normalized(); if (normal.x() < 0 || (normal.x() == 0 && normal.y() < 0) || (normal.x() == 0 && normal.y() == 0 && normal.z() < 0)) { normal = -normal; } return hash_funcs(normal); } }; template <> struct default_elem_ctor { internal::plane_t operator()(internal::paired_model_matrix_ptr_t &k) const { internal::plane_t res{}; res.model_matrices = make_pointer_wrapper(k); return res; } }; } // namespace detail