#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