#pragma once #include #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 struct primitive; EXTERN_C struct PE_API subface { static constexpr uint64_t max_degree = 0; static constexpr internal::equation_system_type eq_sys_type = internal::equation_system_type::invalid; 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; virtual std::function fetch_sdf_evaluator() const = 0; virtual std::function fetch_sdf_grad_evaluator() const = 0; virtual std::function fetch_point_by_param_evaluator() const = 0; virtual std::function fetch_param_mapping_evaluator() const = 0; virtual std::function fetch_curve_constraint_evaluator( internal::parameter_u_t constraint_var_type, double u) const = 0; virtual std::function fetch_curve_constraint_evaluator( internal::parameter_v_t constraint_var_type, double v) const = 0; virtual std::function fetch_solver_evaluator() const = 0; virtual Eigen::AlignedBox3d local_aabb() const = 0; primitive_data_center_t *data_center{nullptr}; internal::paired_model_matrix *model_matrices{nullptr}; internal::transform_block &raw_local_to_world() const; internal::transform_block &raw_world_to_local() const; protected: friend struct primitive; Eigen::Vector3d local_to_world_scale() const; Eigen::Matrix3d trans_world_to_local_linear() const; // CAUTION: all transformation should be applied before acquiring world_to_local // CAUTION: combine flipped subfaces if needed, and return if reversed // CAUTION: always keep characteristic part's first element as positive (flip full transformation instead) to combine // flipped subfaces // NOTE: to avoid any specialization, always keep the characteristic part in the first row/column, which should be impled by // subface's presentation // return: [ptr to changed paired_model_matrix, is_reversed] std::pair apply_transform(internal::transform_type, Eigen::Vector4d); };