#pragma once
#include
#include
#include
#include
namespace internal
{
/**
* @brief Numerical integrator for parametric surfaces with trimming curves.
*
* This class computes integrals (e.g., area, mass, etc.) over trimmed parametric surfaces
* by subdividing the parameter domain and applying Gaussian quadrature.
*
* The integrator does not own the input data; it holds const references to ensure zero-copy semantics.
* Users must ensure that the lifetime of input data exceeds that of the integrator.
*/
class SI_API integrator_t
{
public:
/**
* @note This constructor does not copy the data; it stores const references.
* The caller is responsible for ensuring the validity of the referenced data
* throughout the lifetime of this integrator.
*/
integrator_t(const stl_vector_mp>& surfaces,
const flat_hash_map_mp& uv_planes);
/// Default destructor
~integrator_t() = default;
double calculate(int gauss_order,
double (*func)(double u,
double v,
const Eigen::Vector3d& p,
const Eigen::Vector3d& dU,
const Eigen::Vector3d& dV)) const;
double calculate_one_subface(const subface& subface,
const parametric_plane_t& param_plane,
const stl_vector_mp& chain_bboxes,
int gauss_order,
double (*func)(double u,
double v,
const Eigen::Vector3d& p,
const Eigen::Vector3d& dU,
const Eigen::Vector3d& dV)) const;
private:
/// Non-owning reference to the list of subfaces
const stl_vector_mp>& m_subfaces;
/// Non-owning reference to the map of parametric planes (ID -> parametric_plane_t)
const flat_hash_map_mp& m_uv_planes;
// Precomputed bounding boxes for each chain in each parametric plane
flat_hash_map_mp> m_chain_bboxes_hash{};
stl_vector_mp compute_u_breaks(const parametric_plane_t& param_plane, double u_min, double u_max) const;
void find_v_intersections_at_u(const subface& subface,
const parametric_plane_t& param_plane,
const stl_vector_mp& chain_bboxes,
double u_val,
double v_min,
double v_max,
stl_vector_mp& intersections,
stl_vector_mp& intersected_chains) const;
bool is_edge_inside_domain(const stl_vector_mp>& chain_group_indices,
uint16_t chain_idx1,
uint16_t chain_idx2) const;
bool is_u_near_singularity(double u, double tol = 1e-6) const;
void sort_and_unique_with_tol(stl_vector_mp& vec, double epsilon = 1e-8) const;
};
double newton_method(const std::function& F,
double v_initial,
double tolerance = 1e-8,
int max_iterations = 100);
double area_integrand(double u, double v, const Eigen::Vector3d& p, const Eigen::Vector3d& dU, const Eigen::Vector3d& dV)
{
return 1.0;
}
// Integrate (1/3) * r · n dA over all subfaces
double volume_integrand(double u, double v, const Eigen::Vector3d& p, const Eigen::Vector3d& dU, const Eigen::Vector3d& dV)
{
Eigen::Vector3d cross = dU.cross(dV);
return (p.dot(cross)) / 3.0; // (1/3) * (x dydz + y dzdx + z dxdy)
};
} // namespace internal