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.
166 lines
7.7 KiB
166 lines
7.7 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>;
|
|
|
|
enum class periodical_state_t : uint8_t { invalid = 0, near_cycle_start = 1, near_cycle_end = 2, on_cycle = 3 };
|
|
|
|
static inline periodical_state_t operator|(const periodical_state_t &x, const periodical_state_t &y)
|
|
{
|
|
return static_cast<periodical_state_t>(static_cast<uint8_t>(x) | static_cast<uint8_t>(y));
|
|
}
|
|
|
|
static inline periodical_state_t operator&(const periodical_state_t &x, const periodical_state_t &y)
|
|
{
|
|
return static_cast<periodical_state_t>(static_cast<uint8_t>(x) & static_cast<uint8_t>(y));
|
|
}
|
|
|
|
static inline bool operator>(const periodical_state_t &lhs, const periodical_state_t &rhs)
|
|
{
|
|
return static_cast<uint8_t>(lhs) > static_cast<uint8_t>(rhs);
|
|
}
|
|
|
|
static inline bool operator>=(const periodical_state_t &lhs, const periodical_state_t &rhs)
|
|
{
|
|
return static_cast<uint8_t>(lhs) >= static_cast<uint8_t>(rhs);
|
|
}
|
|
|
|
static inline bool operator<(const periodical_state_t &lhs, const periodical_state_t &rhs)
|
|
{
|
|
return static_cast<uint8_t>(lhs) < static_cast<uint8_t>(rhs);
|
|
}
|
|
|
|
static inline bool operator<=(const periodical_state_t &lhs, const periodical_state_t &rhs)
|
|
{
|
|
return static_cast<uint8_t>(lhs) <= static_cast<uint8_t>(rhs);
|
|
}
|
|
} // 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);
|
|
|
|
// return: world position, surface jacobi weight, volume jacobi weight * dot(world position, normal)
|
|
// surface jacobi weight = |local_to_world||trans_world_to_local * normal| * to param jacobi
|
|
// volume jacobi weight = |local_to_world| * to param jacobi
|
|
using map_param_to_point_with_weight_ptr_t = std::tuple<Eigen::Vector4d, double, double> (*)(pointer_wrapper<subface>,
|
|
Eigen::Vector2d);
|
|
|
|
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 &);
|
|
|
|
using decide_periodical_state_ptr_t = std::array<internal::periodical_state_t, 2> (*)(pointer_wrapper<subface>,
|
|
Eigen::Vector4d);
|
|
using geometry_accessor_ptr_t = const void* (*)(pointer_wrapper<subface>);
|
|
|
|
#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::Vector2d map_point_to_param(pointer_wrapper<subface>, Eigen::Vector3d); \
|
|
static std::tuple<Eigen::Vector4d, double, double> map_param_to_point_with_weight(pointer_wrapper<subface>, \
|
|
Eigen::Vector2d); \
|
|
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 &); \
|
|
static std::array<internal::periodical_state_t, 2> decide_periodical_state(pointer_wrapper<subface>, Eigen::Vector4d); \
|
|
static const void* geometry_accessor(pointer_wrapper<subface>); \
|
|
}
|
|
|
|
def_subface_function_impl(plane);
|
|
def_subface_function_impl(sphere);
|
|
def_subface_function_impl(cylinder);
|
|
// def_subface_function_impl(cone);
|
|
def_subface_function_impl(extrude_polyline_side);
|
|
def_subface_function_impl(extrude_helixline_side);
|
|
|
|
#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_point_to_param);
|
|
def_export_get_function_ptr(map_param_to_point_with_weight);
|
|
def_export_get_function_ptr(eval_du_constraint);
|
|
def_export_get_function_ptr(eval_dv_constraint);
|
|
def_export_get_function_ptr(eval_intersection);
|
|
def_export_get_function_ptr(decide_periodical_state);
|
|
def_export_get_function_ptr(geometry_accessor);
|
|
|
|
#undef def_export_get_function_ptr
|
|
|
|
// for getting range for each kind of subface
|
|
// in turn: (end, is_periodical)
|
|
// assume: start is always 0
|
|
PE_API std::pair<double, bool> get_range_u(surface_type);
|
|
PE_API std::pair<double, bool> get_range_v(surface_type);
|
|
|
|
// used for getting position independent periodical state (2pi)
|
|
static inline periodical_state_t common_decide_periodical_state(Eigen::Vector4d local_pos)
|
|
{
|
|
if (local_pos.x() <= 0)
|
|
return periodical_state_t::invalid;
|
|
else if (local_pos.y() < 0)
|
|
return periodical_state_t::near_cycle_end;
|
|
else if (local_pos.y() > 0)
|
|
return periodical_state_t::near_cycle_start;
|
|
else
|
|
return periodical_state_t::on_cycle;
|
|
}
|
|
} // namespace internal
|