diff --git a/surface_integral/interface/SurfaceIntegrator.hpp b/surface_integral/interface/SurfaceIntegrator.hpp index b30f1c9..3640899 100644 --- a/surface_integral/interface/SurfaceIntegrator.hpp +++ b/surface_integral/interface/SurfaceIntegrator.hpp @@ -1,7 +1,10 @@ #pragma once -#include -#include "surface_integral/include/quadrature.hpp" +#include +#include + +#include "flat_index_group.hpp" + namespace internal { @@ -19,46 +22,36 @@ class SurfaceAreaCalculator public: // 构造函数,接受对 subface 的引用 explicit SurfaceAreaCalculator(const subface& surface); - [[deprecated("Use calculate_new() instead")]] SurfaceAreaCalculator(const subface& surface, - const stl_vector_map& u_breaks, - double umin, - double umax, - double vmin, - double vmax); + [[deprecated("Use calculate_new() instead")]] SurfaceAreaCalculator(const subface& surface, + const stl_vector_mp& u_breaks, + double umin, + double umax, + double vmin, + double vmax); SurfaceAreaCalculator(const subface& surface, const parametric_plane& uv_plane); // 设置 u_breaks(裁剪/分割线) - void set_ubreaks(const stl_vector_map& u_breaks); + void set_ubreaks(const stl_vector_mp& u_breaks); // 计算面积主函数 template double calculate(Func&& func, int gauss_order = 3) const; private: - const subface& m_surface; // 引用原始曲面 - stl_vector_map m_u_breaks; // 分割线信息(可选) - parametric_plane m_uv_plane; - double Umin = 0.0; // 参数域范围 - double Umax = 1.0; - double Vmin = 0.0; - double Vmax = 1.0; + const subface& m_surface; // 引用原始曲面 + stl_vector_mp m_u_breaks; // 分割线信息(可选) + parametric_plane m_uv_plane; + double Umin = 0.0; // 参数域范围 + double Umax = 1.0; + double Vmin = 0.0; + double Vmax = 1.0; // 私有辅助函数 // 直线u=u_val与边界的交点 - std::vector find_vertical_intersections(double u_val, - const std::vector& edges, - double v_min, - double v_max); + std::vector find_vertical_intersections(double u_val); - bool is_point_inside_domain(double u, - double v, - const std::vector& outerEdges, - const std::vector& innerEdges, - double u_min, - double u_max, - double v_min, - double v_max); + bool is_point_inside_domain(double u, double v); double newton_method(const std::function& F, double v_initial, double tolerance = 1e-8, diff --git a/surface_integral/interface/flat_index_group.hpp b/surface_integral/interface/flat_index_group.hpp new file mode 100644 index 0000000..ca1bb91 --- /dev/null +++ b/surface_integral/interface/flat_index_group.hpp @@ -0,0 +1,52 @@ +#pragma once + +#include +#include + +struct flat_index_group { + stl_vector_mp index_group{}; /// a list of indices in the group + stl_vector_mp start_indices{}; /// a list of start indices for each group in the flat index group + + inline size_t size() const { return start_indices.size() - 1; } + + struct group_index_looper { + auto begin() const { return counting_iterator{0}; } + + auto end() const { return counting_iterator{static_cast(parent_group.size())}; } + + const flat_index_group& parent_group{}; + }; + + auto group_indices() const { return group_index_looper{*this}; } + + struct group_looper { + auto begin() const + { + return std::next(parent_group.index_group.begin(), *(parent_group.start_indices.begin() + group_idx)); + } + + auto end() const + { + return std::next(parent_group.index_group.begin(), *(parent_group.start_indices.begin() + group_idx + 1)); + } + + const flat_index_group& parent_group{}; + const uint32_t group_idx{}; + }; + + auto group(uint32_t group_idx) const { return group_looper{*this, group_idx}; } + + inline auto group_index_iter_begin() const { return counting_iterator{0}; } + + inline auto group_index_iter_end() const { return counting_iterator{static_cast(size())}; } + + inline auto group_begin(uint32_t group_idx) const + { + return std::next(index_group.begin(), *(start_indices.begin() + group_idx)); + } + + inline auto group_end(uint32_t group_idx) const + { + return std::next(index_group.begin(), *(start_indices.begin() + group_idx + 1)); + } +}; \ No newline at end of file diff --git a/surface_integral/src/SurfaceIntegrator.cpp b/surface_integral/src/SurfaceIntegrator.cpp index 4917f25..865df03 100644 --- a/surface_integral/src/SurfaceIntegrator.cpp +++ b/surface_integral/src/SurfaceIntegrator.cpp @@ -1,6 +1,8 @@ -#include "surface_integral.hpp" // Replace with your actual header path +#include "SurfaceIntegrator.hpp" +#include "quadrature.hpp" #include // For vector and cross product operations #include // For math functions like sqrt +#include namespace internal { @@ -10,7 +12,7 @@ SurfaceAreaCalculator::SurfaceAreaCalculator(const subface& surface) : m_surface // Constructor 2: Initialize with surface and u-breaks (e.g., trimming curves) SurfaceAreaCalculator::SurfaceAreaCalculator(const subface& surface, - const stl_vector_map& u_breaks, + const stl_vector_mp& u_breaks, double umin, double umax, double vmin, @@ -69,11 +71,11 @@ SurfaceAreaCalculator::SurfaceAreaCalculator(const subface& surface, const param } // 转换为 vector 并排序(set 默认是有序的) - m_u_breaks = std::vector(unique_u_values.begin(), unique_u_values.end()); + m_u_breaks = stl_vector_mp(unique_u_values.begin(), unique_u_values.end()); } // Set u-breaks (optional trimming or partitioning lines) -void SurfaceAreaCalculator::set_ubreaks(const stl_vector_map& u_breaks) { m_u_breaks = u_breaks; } +void SurfaceAreaCalculator::set_ubreaks(const stl_vector_mp& u_breaks) { m_u_breaks = u_breaks; } // Main entry point to compute surface area template @@ -168,7 +170,7 @@ std::vector SurfaceAreaCalculator::find_vertical_intersections(double u_ if (v1.x() != v2.x()) { // "The line segment is vertical (u₁ == u₂), so there is no unique v value corresponding to the given u." double v_initial = v1.y() + (v2.y() - v1.y()) * (u_val - v1.x()) / (v2.x() - v1.x()); - auto curve_evaluator = m_surface.fetch_curve_constraint_evaluator(u); + auto curve_evaluator = m_surface.fetch_curve_constraint_evaluator(u_val); auto solver_evaluator = m_surface.fetch_solver_evaluator(); auto target_function = [&](double v) -> equation_intermediate_t { constraint_curve_intermediate temp_res = curve_evaluator(v); diff --git a/surface_integral/xmake.lua b/surface_integral/xmake.lua new file mode 100644 index 0000000..fd919bd --- /dev/null +++ b/surface_integral/xmake.lua @@ -0,0 +1,7 @@ +add_requires("gtest") + +internal_library("surface_integral", "SI", os.scriptdir()) + add_rules("config.indirect_predicates.flags") + add_deps("primitive_process", "shared_module") + +