You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

98 lines
4.5 KiB

#pragma once
#include <variant>
#include <macros.h>
#include <data/data_type.hpp>
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<double, 3, 2> grad_f; // [[df/du, df/dv]; [dg/du, dg/dv];
// [dh/du, dh/dv]]
};
using equation_intermediate_t = std::variant<implicit_equation_intermediate, parametric_equation_intermediate>;
} // 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<subface>, Eigen::Vector3d);
using eval_sdf_grad_ptr_t = Eigen::Vector3d (*)(pointer_wrapper<subface>, Eigen::Vector3d);
using map_param_to_point_ptr_t = Eigen::Vector4d (*)(pointer_wrapper<subface>, Eigen::Vector2d);
using map_point_to_param_ptr_t = Eigen::Vector2d (*)(pointer_wrapper<subface>, Eigen::Vector3d);
using eval_du_constraint_ptr_t = internal::constraint_curve_intermediate (*)(pointer_wrapper<subface>, Eigen::Vector2d);
using eval_dv_constraint_ptr_t = internal::constraint_curve_intermediate (*)(pointer_wrapper<subface>, Eigen::Vector2d);
using eval_intersection_ptr_t = internal::equation_intermediate_t (*)(pointer_wrapper<subface>,
const internal::constraint_curve_intermediate &);
#define def_subface_function_impl(subface_name) \
struct subface_name##_function_impl { \
static double eval_sdf(pointer_wrapper<subface>, Eigen::Vector3d); \
static Eigen::Vector3d eval_sdf_grad(pointer_wrapper<subface>, Eigen::Vector3d); \
static Eigen::Vector4d map_param_to_point(pointer_wrapper<subface>, Eigen::Vector2d); \
static Eigen::Vector2d map_point_to_param(pointer_wrapper<subface>, Eigen::Vector3d); \
static internal::constraint_curve_intermediate eval_du_constraint(pointer_wrapper<subface>, Eigen::Vector2d); \
static internal::constraint_curve_intermediate eval_dv_constraint(pointer_wrapper<subface>, Eigen::Vector2d); \
static internal::equation_intermediate_t eval_intersection(pointer_wrapper<subface>, \
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