|
|
@ -9,10 +9,10 @@ namespace internal |
|
|
{ |
|
|
{ |
|
|
|
|
|
|
|
|
// Constructor 1: Initialize only with a reference to the surface
|
|
|
// Constructor 1: Initialize only with a reference to the surface
|
|
|
SurfaceAreaCalculator::SurfaceAreaCalculator(const subface& surface) : m_surface(surface) {} |
|
|
integrator_t::integrator_t(const subface& surface) : m_surface(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, |
|
|
integrator_t::integrator_t(const subface& surface, |
|
|
const stl_vector_mp<double>& u_breaks, |
|
|
const stl_vector_mp<double>& u_breaks, |
|
|
double umin, |
|
|
double umin, |
|
|
double umax, |
|
|
double umax, |
|
|
@ -22,7 +22,7 @@ SurfaceAreaCalculator::SurfaceAreaCalculator(const subface& surfac |
|
|
{ |
|
|
{ |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
SurfaceAreaCalculator::SurfaceAreaCalculator(const subface& surface, const parametric_plane& uv_plane) |
|
|
integrator_t::integrator_t(const subface& surface, const parametric_plane& uv_plane) |
|
|
: m_surface(surface), m_uv_plane(uv_plane), Umin(0.0), Umax(0.0), Vmin(0.0), Vmax(0.0) |
|
|
: m_surface(surface), m_uv_plane(uv_plane), Umin(0.0), Umax(0.0), Vmin(0.0), Vmax(0.0) |
|
|
{ |
|
|
{ |
|
|
if (!uv_plane.chain_vertices.empty()) { |
|
|
if (!uv_plane.chain_vertices.empty()) { |
|
|
@ -76,11 +76,11 @@ SurfaceAreaCalculator::SurfaceAreaCalculator(const subface& surface, const param |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Set u-breaks (optional trimming or partitioning lines)
|
|
|
// Set u-breaks (optional trimming or partitioning lines)
|
|
|
void SurfaceAreaCalculator::set_ubreaks(const stl_vector_mp<double>& u_breaks) { m_u_breaks = u_breaks; } |
|
|
void integrator_t::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> |
|
|
double SurfaceAreaCalculator::calculate(Func&& func, int gauss_order) const |
|
|
double integrator_t::calculate(Func&& func, int gauss_order) const |
|
|
{ |
|
|
{ |
|
|
auto solver = m_surface.fetch_solver_evaluator(); |
|
|
auto solver = m_surface.fetch_solver_evaluator(); |
|
|
// 在u方向进行高斯积分
|
|
|
// 在u方向进行高斯积分
|
|
|
@ -151,8 +151,8 @@ double SurfaceAreaCalculator::calculate(Func&& func, int gauss_order) const |
|
|
return integral; |
|
|
return integral; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 在 SurfaceAreaCalculator 类中添加:
|
|
|
// 在 integrator_t 类中添加:
|
|
|
double SurfaceAreaCalculator::compute_volume(int gauss_order) const |
|
|
double integrator_t::compute_volume(int gauss_order) const |
|
|
{ |
|
|
{ |
|
|
double total_volume = 0.0; |
|
|
double total_volume = 0.0; |
|
|
|
|
|
|
|
|
@ -217,7 +217,7 @@ double SurfaceAreaCalculator::compute_volume(int gauss_order) const |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 直线u=u_val与边界的交点
|
|
|
// 直线u=u_val与边界的交点
|
|
|
std::vector<double> SurfaceAreaCalculator::find_vertical_intersections(double u_val) const |
|
|
std::vector<double> integrator_t::find_vertical_intersections(double u_val) const |
|
|
{ |
|
|
{ |
|
|
std::vector<double> intersections; |
|
|
std::vector<double> intersections; |
|
|
std::vector<int32_t> uPositionFlags; |
|
|
std::vector<int32_t> uPositionFlags; |
|
|
@ -246,9 +246,11 @@ std::vector<double> SurfaceAreaCalculator::find_vertical_intersections(double 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(parameter_u_t{}, u_val); |
|
|
auto curve_evaluator = m_surface.fetch_curve_constraint_evaluator(parameter_u_t{}, 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) -> internal::implicit_equation_intermediate { |
|
|
constraint_curve_intermediate temp_res = curve_evaluator(v); |
|
|
constraint_curve_intermediate temp_res = curve_evaluator(v); |
|
|
return solver_evaluator(std::move(temp_res)); |
|
|
auto full_res = solver_evaluator(std::move(temp_res)); |
|
|
|
|
|
// ensure solver_eval returns implicit_equation_intermediate)
|
|
|
|
|
|
return std::get<internal::implicit_equation_intermediate>(full_res); |
|
|
}; |
|
|
}; |
|
|
double v_solution = newton_method(target_function, v_initial); |
|
|
double v_solution = newton_method(target_function, v_initial); |
|
|
intersections.push_back(v_solution); |
|
|
intersections.push_back(v_solution); |
|
|
@ -272,7 +274,7 @@ std::vector<double> SurfaceAreaCalculator::find_vertical_intersections(double u_ |
|
|
NOTE: when v_intersect - v < threshold, further checks are required to accurately determine if the intersection point lies |
|
|
NOTE: when v_intersect - v < threshold, further checks are required to accurately determine if the intersection point lies |
|
|
precisely on the boundary segment. |
|
|
precisely on the boundary segment. |
|
|
*/ |
|
|
*/ |
|
|
bool SurfaceAreaCalculator::is_point_inside_domain(double u, double v) const |
|
|
bool integrator_t::is_point_inside_domain(double u, double v) const |
|
|
{ |
|
|
{ |
|
|
bool is_implicit_equation_intermediate = m_surface.is_implicit_equation_intermediate(); |
|
|
bool is_implicit_equation_intermediate = m_surface.is_implicit_equation_intermediate(); |
|
|
uint32_t group_idx = 0, intersection_count = 0; |
|
|
uint32_t group_idx = 0, intersection_count = 0; |
|
|
@ -293,7 +295,7 @@ bool SurfaceAreaCalculator::is_point_inside_domain(double u, double v) const |
|
|
if (is_implicit_equation_intermediate) { |
|
|
if (is_implicit_equation_intermediate) { |
|
|
auto curve_evaluator = m_surface.fetch_curve_constraint_evaluator(parameter_u_t{}, u); |
|
|
auto curve_evaluator = m_surface.fetch_curve_constraint_evaluator(parameter_u_t{}, u); |
|
|
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) -> internal::implicit_equation_intermediate { |
|
|
constraint_curve_intermediate temp_res = curve_evaluator(v); |
|
|
constraint_curve_intermediate temp_res = curve_evaluator(v); |
|
|
auto full_res = solver_evaluator(std::move(temp_res)); |
|
|
auto full_res = solver_evaluator(std::move(temp_res)); |
|
|
// ensure solver_eval returns implicit_equation_intermediate)
|
|
|
// ensure solver_eval returns implicit_equation_intermediate)
|
|
|
@ -316,7 +318,7 @@ bool SurfaceAreaCalculator::is_point_inside_domain(double u, double v) const |
|
|
return intersection_count % 2 == 1; // in domain
|
|
|
return intersection_count % 2 == 1; // in domain
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
bool SurfaceAreaCalculator::is_u_near_singularity(double u, double tol) const |
|
|
bool integrator_t::is_u_near_singularity(double u, double tol) const |
|
|
{ |
|
|
{ |
|
|
for (auto idx : m_uv_plane.singularity_vertices) { |
|
|
for (auto idx : m_uv_plane.singularity_vertices) { |
|
|
double singular_u = m_uv_plane.chain_vertices[idx].x(); |
|
|
double singular_u = m_uv_plane.chain_vertices[idx].x(); |
|
|
@ -330,7 +332,7 @@ bool SurfaceAreaCalculator::is_u_near_singularity(double u, double tol) const |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void SurfaceAreaCalculator::sort_and_unique_with_tol(std::vector<double>& vec, double epsilon) const |
|
|
void integrator_t::sort_and_unique_with_tol(std::vector<double>& vec, double epsilon) const |
|
|
{ |
|
|
{ |
|
|
if (vec.empty()) return; |
|
|
if (vec.empty()) return; |
|
|
|
|
|
|
|
|
@ -351,8 +353,8 @@ void SurfaceAreaCalculator::sort_and_unique_with_tol(std::vector<double>& vec, d |
|
|
double newton_method( |
|
|
double newton_method( |
|
|
const std::function<internal::implicit_equation_intermediate(double)>& F, |
|
|
const std::function<internal::implicit_equation_intermediate(double)>& F, |
|
|
double v_initial, |
|
|
double v_initial, |
|
|
double tolerance = 1e-6, |
|
|
double tolerance, |
|
|
int max_iterations = 20) |
|
|
int max_iterations) |
|
|
{ |
|
|
{ |
|
|
double v = v_initial; |
|
|
double v = v_initial; |
|
|
|
|
|
|
|
|
|