#pragma once #include #include #include namespace internal { /* tags for identifying which equation system is used for the * subface */ enum class equation_system_type { invalid, implicit, parametric }; /* type-tags for identifying constrained parameter var */ struct parameter_u_t { } static inline parameter_u; struct parameter_v_t { } static inline parameter_v; // CAUTION: all should be in world space struct constraint_curve_intermediate { Eigen::Vector4d f; // x(t), y(t), z(t), 1 Eigen::Vector4d grad_f; // dx/dt, dy/dt, dz/dt, 0 }; struct implicit_equation_intermediate { double f; double df; }; struct parametric_equation_intermediate { Eigen::Vector3d f; // approx. surface point by surface, can also be seen // as f(u,v), g(u,v) and h(u,v) Eigen::Matrix grad_f; // [[df/du, df/dv]; [dg/du, dg/dv]; // [dh/du, dh/dv]] }; using equation_intermediate_t = std::variant; } // namespace internal EXTERN_C struct PE_API subface : internal::paired_model_matrix { subface() noexcept = default; subface(const subface &) noexcept = default; subface(subface &&) noexcept = default; subface &operator=(const subface &) noexcept = default; subface &operator=(subface &&) noexcept = default; virtual ~subface() noexcept = default; Eigen::Vector3d local_to_world_scale() const { return local_to_world.linear().colwise().norm(); } Eigen::Matrix3d trans_world_to_local_linear() const { return world_to_local.linear().transpose(); } }; namespace internal { using eval_sdf_ptr_t = double (*)(pointer_wrapper, Eigen::Vector3d); using eval_sdf_grad_ptr_t = Eigen::Vector3d (*)(pointer_wrapper, Eigen::Vector3d); using map_param_to_point_ptr_t = Eigen::Vector4d (*)(pointer_wrapper, Eigen::Vector2d); using map_point_to_param_ptr_t = Eigen::Vector2d (*)(pointer_wrapper, Eigen::Vector3d); using eval_du_constraint_ptr_t = internal::constraint_curve_intermediate (*)(pointer_wrapper, Eigen::Vector2d); using eval_dv_constraint_ptr_t = internal::constraint_curve_intermediate (*)(pointer_wrapper, Eigen::Vector2d); using eval_intersection_ptr_t = internal::equation_intermediate_t (*)(pointer_wrapper, const internal::constraint_curve_intermediate &); #define def_subface_function_impl(subface_name) \ struct subface_name##_function_impl { \ static double eval_sdf(pointer_wrapper, Eigen::Vector3d); \ static Eigen::Vector3d eval_sdf_grad(pointer_wrapper, Eigen::Vector3d); \ static Eigen::Vector4d map_param_to_point(pointer_wrapper, Eigen::Vector2d); \ static Eigen::Vector2d map_point_to_param(pointer_wrapper, Eigen::Vector3d); \ static internal::constraint_curve_intermediate eval_du_constraint(pointer_wrapper, Eigen::Vector2d); \ static internal::constraint_curve_intermediate eval_dv_constraint(pointer_wrapper, Eigen::Vector2d); \ static internal::equation_intermediate_t eval_intersection(pointer_wrapper, \ const internal::constraint_curve_intermediate &); \ } def_subface_function_impl(plane); def_subface_function_impl(sphere); def_subface_function_impl(cylinder); // def_subface_function_impl(cone); #undef def_subface_function_impl #define def_export_get_function_ptr(func_name) PE_API func_name##_ptr_t get_##func_name##_ptr(surface_type) def_export_get_function_ptr(eval_sdf); def_export_get_function_ptr(eval_sdf_grad); def_export_get_function_ptr(map_param_to_point); def_export_get_function_ptr(map_point_to_param); def_export_get_function_ptr(eval_du_constraint); def_export_get_function_ptr(eval_dv_constraint); def_export_get_function_ptr(eval_intersection); #undef def_export_get_function_ptr } // namespace internal