Browse Source

to&fix: compilable version after feat integrator

feat-integrator
mckay 4 weeks ago
parent
commit
24bd20cc42
  1. 7
      frontend/src/implicit_surface_network_solver.cpp
  2. 2
      frontend/xmake.lua
  3. 13
      surface_integral/interface/SurfaceIntegrator.hpp
  4. 34
      surface_integral/src/SurfaceIntegrator.cpp
  5. 32
      surface_integral/test/SurfaceIntegrator_test.cpp
  6. 9
      surface_integral/xmake.lua

7
frontend/src/implicit_surface_network_solver.cpp

@ -1,4 +1,5 @@
#include <implicit_surface_network_solver.hpp>
#include <SurfaceIntegrator.hpp>
EXTERN_C_BEGIN
@ -8,11 +9,15 @@ void implicit_network_solver::generate_polymesh(stl_vector_mp<Eigen::Vector3d>&
{
// generate polymesh
m_timers.push_timer("generate_polymesh");
flat_hash_map_mp<uint32_t, parameteric_plane_t> output_parameteric_planes;
build_implicit_network_by_blobtree(m_settings,
*m_blobtree,
output_vertices,
output_polygon_faces,
output_vertex_counts_of_face);
output_vertex_counts_of_face,
output_parameteric_planes);
//integrator_t integrator(const subface& surface, const parametric_plane& uv_plane);
m_timers.pop_timer("generate_polymesh");
}

2
frontend/xmake.lua

@ -1,4 +1,4 @@
exposed_library("frontend", os.scriptdir())
add_rules("config.indirect_predicates.flags")
-- add_rules("library.force.distribute.header", {headers = path.join(os.scriptdir(), "interface", "construct_helper.hpp")})
add_deps("implicit_surface_network_process", "shared_module")
add_deps("implicit_surface_network_process", "surface_integrator","shared_module")

13
surface_integral/interface/SurfaceIntegrator.hpp

@ -1,6 +1,7 @@
#pragma once
#include <base/subface.hpp>
#include <process.hpp>
#include <container/stl_alias.hpp>
#include <container/wrapper/flat_index_group.hpp>
@ -16,19 +17,19 @@ struct parametric_plane {
stl_vector_mp<uint32_t> polar_vertices{}; // 极性顶点,即两个连接顶点周围的最小/最大 x/y
stl_vector_mp<uint32_t> parallel_start_vertices{}; // 平行起始顶点,即边 {v, v + 1} 平行于 x/y 轴
};
class SurfaceAreaCalculator
class SI_API integrator_t
{
public:
// 构造函数,接受对 subface 的引用
explicit SurfaceAreaCalculator(const subface& surface);
[[deprecated("Use calculate_new() instead")]] SurfaceAreaCalculator(const subface& surface,
explicit integrator_t(const subface& surface);
[[deprecated("Use calculate_new() instead")]] integrator_t(const subface& surface,
const stl_vector_mp<double>& u_breaks,
double umin,
double umax,
double vmin,
double vmax);
SurfaceAreaCalculator(const subface& surface, const parametric_plane& uv_plane);
integrator_t(const subface& surface, const parametric_plane& uv_plane);
// 设置 u_breaks(裁剪/分割线)
@ -59,7 +60,7 @@ private:
};
double newton_method(const std::function<equation_intermediate_t(double)>& F,
SI_API double newton_method(const std::function<internal::implicit_equation_intermediate(double)>& F,
double v_initial,
double tolerance = 1e-8,
int max_iterations = 100);

34
surface_integral/src/SurfaceIntegrator.cpp

@ -9,10 +9,10 @@ namespace internal
{
// 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)
SurfaceAreaCalculator::SurfaceAreaCalculator(const subface& surface,
integrator_t::integrator_t(const subface& surface,
const stl_vector_mp<double>& u_breaks,
double umin,
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)
{
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)
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
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();
// 在u方向进行高斯积分
@ -151,8 +151,8 @@ double SurfaceAreaCalculator::calculate(Func&& func, int gauss_order) const
return integral;
}
// 在 SurfaceAreaCalculator 类中添加:
double SurfaceAreaCalculator::compute_volume(int gauss_order) const
// 在 integrator_t 类中添加:
double integrator_t::compute_volume(int gauss_order) const
{
double total_volume = 0.0;
@ -217,7 +217,7 @@ double SurfaceAreaCalculator::compute_volume(int gauss_order) const
}
// 直线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<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());
auto curve_evaluator = m_surface.fetch_curve_constraint_evaluator(parameter_u_t{}, u_val);
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);
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);
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
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();
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) {
auto curve_evaluator = m_surface.fetch_curve_constraint_evaluator(parameter_u_t{}, u);
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);
auto full_res = solver_evaluator(std::move(temp_res));
// 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
}
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) {
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;
}
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;
@ -351,8 +353,8 @@ void SurfaceAreaCalculator::sort_and_unique_with_tol(std::vector<double>& vec, d
double newton_method(
const std::function<internal::implicit_equation_intermediate(double)>& F,
double v_initial,
double tolerance = 1e-6,
int max_iterations = 20)
double tolerance,
int max_iterations)
{
double v = v_initial;

32
surface_integral/test/SurfaceIntegrator_test.cpp

@ -1,24 +1,24 @@
#include <gtest/gtest.h>
#include "SurfaceIntegrator.hpp"
#include <timer/scoped_timer.hpp>
using namespace internal;
#include <SurfaceIntegrator.hpp>
// 一个简单的方程:f(v) = v^2 - 2, df = 2v,根为 sqrt(2)
TEST(SurfaceAreaCalculatorTest, NewtonMethodConverges)
int main()
{
labelled_timers_manager timer{};
auto F = [](double v) -> equation_intermediate_t {
implicit_equation_intermediate iei;
iei.f = v * v - 2.0;
iei.df = 2.0 * v;
return equation_intermediate_t{iei};
};
// box_descriptor_t box{
// {0., 0., 0.},
// {1., 1., 1.}
// };
// primitive_node_t node{PRIMITIVE_TYPE_BOX, &box};
double v_initial = 1.0;
double tolerance = 1e-8;
int max_iterations = 20;
// timer.push_timer("run-time under 10^6 loops (old)");
double root = newton_method(F, v_initial, tolerance, max_iterations);
// for (auto i = 0; i < 1'000'000; ++i) { auto result = evaluate(node, Eigen::Vector3d::Ones() * 2); }
EXPECT_NEAR(root, std::sqrt(2.0), tolerance);
// timer.pop_timer("run-time under 10^6 loops (old)");
// timer.print();
return 0;
}

9
surface_integral/xmake.lua

@ -1,13 +1,14 @@
add_requires("gtest")
internal_library("surface_integral", "SI", os.scriptdir())
internal_library("surface_integrator", "SI", os.scriptdir())
add_rules("config.indirect_predicates.flags")
add_deps("primitive_process", "shared_module")
add_deps("primitive_process", "implicit_surface_network_process", "shared_module")
-- add Google Test target
target("newton_method_test")
set_kind("binary")
add_deps("surface_integral") -- depend on the internal library surface_integral
add_deps("surface_integrator") -- depend on the internal library surface_integral
add_files("test/SurfaceIntegrator_test.cpp")
add_packages("gtest")
target_end()
target_end()

Loading…
Cancel
Save