Browse Source

do:Refactor SurfaceAreaCalculator and add flat_index_group structure: update constructors, improve data types, and enhance integration methods

wch
mckay 3 months ago
parent
commit
1c710d962c
  1. 49
      surface_integral/interface/SurfaceIntegrator.hpp
  2. 52
      surface_integral/interface/flat_index_group.hpp
  3. 12
      surface_integral/src/SurfaceIntegrator.cpp
  4. 7
      surface_integral/xmake.lua

49
surface_integral/interface/SurfaceIntegrator.hpp

@ -1,7 +1,10 @@
#pragma once #pragma once
#include <primitive_process/interface/base/subface.hpp> #include <base/subface.hpp>
#include "surface_integral/include/quadrature.hpp" #include <container/stl_alias.hpp>
#include "flat_index_group.hpp"
namespace internal namespace internal
{ {
@ -19,46 +22,36 @@ class SurfaceAreaCalculator
public: public:
// 构造函数,接受对 subface 的引用 // 构造函数,接受对 subface 的引用
explicit SurfaceAreaCalculator(const subface& surface); explicit SurfaceAreaCalculator(const subface& surface);
[[deprecated("Use calculate_new() instead")]] SurfaceAreaCalculator(const subface& surface, [[deprecated("Use calculate_new() instead")]] SurfaceAreaCalculator(const subface& surface,
const stl_vector_map<double>& u_breaks, const stl_vector_mp<double>& u_breaks,
double umin, double umin,
double umax, double umax,
double vmin, double vmin,
double vmax); double vmax);
SurfaceAreaCalculator(const subface& surface, const parametric_plane& uv_plane); SurfaceAreaCalculator(const subface& surface, const parametric_plane& uv_plane);
// 设置 u_breaks(裁剪/分割线) // 设置 u_breaks(裁剪/分割线)
void set_ubreaks(const stl_vector_map<double>& u_breaks); void set_ubreaks(const stl_vector_mp<double>& u_breaks);
// 计算面积主函数 // 计算面积主函数
template <typename Func> template <typename Func>
double calculate(Func&& func, int gauss_order = 3) const; double calculate(Func&& func, int gauss_order = 3) const;
private: private:
const subface& m_surface; // 引用原始曲面 const subface& m_surface; // 引用原始曲面
stl_vector_map<double> m_u_breaks; // 分割线信息(可选) stl_vector_mp<double> m_u_breaks; // 分割线信息(可选)
parametric_plane m_uv_plane; parametric_plane m_uv_plane;
double Umin = 0.0; // 参数域范围 double Umin = 0.0; // 参数域范围
double Umax = 1.0; double Umax = 1.0;
double Vmin = 0.0; double Vmin = 0.0;
double Vmax = 1.0; double Vmax = 1.0;
// 私有辅助函数 // 私有辅助函数
// 直线u=u_val与边界的交点 // 直线u=u_val与边界的交点
std::vector<double> find_vertical_intersections(double u_val, std::vector<double> find_vertical_intersections(double u_val);
const std::vector<Handle(Geom2d_Curve)>& edges,
double v_min,
double v_max);
bool is_point_inside_domain(double u, bool is_point_inside_domain(double u, double v);
double v,
const std::vector<Handle(Geom2d_Curve)>& outerEdges,
const std::vector<Handle(Geom2d_Curve)>& innerEdges,
double u_min,
double u_max,
double v_min,
double v_max);
double newton_method(const std::function<equation_intermediate_t(double)>& F, double newton_method(const std::function<equation_intermediate_t(double)>& F,
double v_initial, double v_initial,
double tolerance = 1e-8, double tolerance = 1e-8,

52
surface_integral/interface/flat_index_group.hpp

@ -0,0 +1,52 @@
#pragma once
#include <container/stl_alias.hpp>
#include <iterator/counting_iterator.hpp>
struct flat_index_group {
stl_vector_mp<uint32_t> index_group{}; /// a list of indices in the group
stl_vector_mp<uint32_t> 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<uint32_t>{0}; }
auto end() const { return counting_iterator<uint32_t>{static_cast<uint32_t>(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<uint32_t>{0}; }
inline auto group_index_iter_end() const { return counting_iterator<uint32_t>{static_cast<uint32_t>(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));
}
};

12
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 <Eigen/Geometry> // For vector and cross product operations #include <Eigen/Geometry> // For vector and cross product operations
#include <cmath> // For math functions like sqrt #include <cmath> // For math functions like sqrt
#include <set>
namespace internal 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) // Constructor 2: Initialize with surface and u-breaks (e.g., trimming curves)
SurfaceAreaCalculator::SurfaceAreaCalculator(const subface& surface, SurfaceAreaCalculator::SurfaceAreaCalculator(const subface& surface,
const stl_vector_map<double>& u_breaks, const stl_vector_mp<double>& u_breaks,
double umin, double umin,
double umax, double umax,
double vmin, double vmin,
@ -69,11 +71,11 @@ SurfaceAreaCalculator::SurfaceAreaCalculator(const subface& surface, const param
} }
// 转换为 vector 并排序(set 默认是有序的) // 转换为 vector 并排序(set 默认是有序的)
m_u_breaks = std::vector<double>(unique_u_values.begin(), unique_u_values.end()); m_u_breaks = stl_vector_mp<double>(unique_u_values.begin(), unique_u_values.end());
} }
// Set u-breaks (optional trimming or partitioning lines) // Set u-breaks (optional trimming or partitioning lines)
void SurfaceAreaCalculator::set_ubreaks(const stl_vector_map<double>& u_breaks) { m_u_breaks = u_breaks; } void SurfaceAreaCalculator::set_ubreaks(const stl_vector_mp<double>& u_breaks) { m_u_breaks = u_breaks; }
// Main entry point to compute surface area // Main entry point to compute surface area
template <typename Func> template <typename Func>
@ -168,7 +170,7 @@ std::vector<double> SurfaceAreaCalculator::find_vertical_intersections(double u_
if (v1.x() != v2.x()) { if (v1.x() != v2.x()) {
// "The line segment is vertical (u₁ == u₂), so there is no unique v value corresponding to the given u." // "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()); 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 solver_evaluator = m_surface.fetch_solver_evaluator();
auto target_function = [&](double v) -> equation_intermediate_t { auto target_function = [&](double v) -> equation_intermediate_t {
constraint_curve_intermediate temp_res = curve_evaluator(v); constraint_curve_intermediate temp_res = curve_evaluator(v);

7
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")
Loading…
Cancel
Save