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 <implicit_surface_network_solver.hpp>
#include <SurfaceIntegrator.hpp>
EXTERN_C_BEGIN EXTERN_C_BEGIN
@ -8,11 +9,15 @@ void implicit_network_solver::generate_polymesh(stl_vector_mp<Eigen::Vector3d>&
{ {
// generate polymesh // generate polymesh
m_timers.push_timer("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, build_implicit_network_by_blobtree(m_settings,
*m_blobtree, *m_blobtree,
output_vertices, output_vertices,
output_polygon_faces, 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"); m_timers.pop_timer("generate_polymesh");
} }

2
frontend/xmake.lua

@ -1,4 +1,4 @@
exposed_library("frontend", os.scriptdir()) exposed_library("frontend", os.scriptdir())
add_rules("config.indirect_predicates.flags") add_rules("config.indirect_predicates.flags")
-- add_rules("library.force.distribute.header", {headers = path.join(os.scriptdir(), "interface", "construct_helper.hpp")}) -- 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 #pragma once
#include <base/subface.hpp> #include <base/subface.hpp>
#include <process.hpp>
#include <container/stl_alias.hpp> #include <container/stl_alias.hpp>
#include <container/wrapper/flat_index_group.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> polar_vertices{}; // 极性顶点,即两个连接顶点周围的最小/最大 x/y
stl_vector_mp<uint32_t> parallel_start_vertices{}; // 平行起始顶点,即边 {v, v + 1} 平行于 x/y 轴 stl_vector_mp<uint32_t> parallel_start_vertices{}; // 平行起始顶点,即边 {v, v + 1} 平行于 x/y 轴
}; };
class SurfaceAreaCalculator class SI_API integrator_t
{ {
public: public:
// 构造函数,接受对 subface 的引用 // 构造函数,接受对 subface 的引用
explicit SurfaceAreaCalculator(const subface& surface); explicit integrator_t(const subface& surface);
[[deprecated("Use calculate_new() instead")]] SurfaceAreaCalculator(const subface& surface, [[deprecated("Use calculate_new() instead")]] 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,
double vmin, double vmin,
double vmax); double vmax);
SurfaceAreaCalculator(const subface& surface, const parametric_plane& uv_plane); integrator_t(const subface& surface, const parametric_plane& uv_plane);
// 设置 u_breaks(裁剪/分割线) // 设置 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 v_initial,
double tolerance = 1e-8, double tolerance = 1e-8,
int max_iterations = 100); 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 // 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;

32
surface_integral/test/SurfaceIntegrator_test.cpp

@ -1,24 +1,24 @@
#include <gtest/gtest.h> #include <timer/scoped_timer.hpp>
#include "SurfaceIntegrator.hpp"
using namespace internal; #include <SurfaceIntegrator.hpp>
// 一个简单的方程:f(v) = v^2 - 2, df = 2v,根为 sqrt(2) int main()
TEST(SurfaceAreaCalculatorTest, NewtonMethodConverges)
{ {
labelled_timers_manager timer{};
auto F = [](double v) -> equation_intermediate_t { // box_descriptor_t box{
implicit_equation_intermediate iei; // {0., 0., 0.},
iei.f = v * v - 2.0; // {1., 1., 1.}
iei.df = 2.0 * v; // };
return equation_intermediate_t{iei}; // primitive_node_t node{PRIMITIVE_TYPE_BOX, &box};
};
double v_initial = 1.0; // timer.push_timer("run-time under 10^6 loops (old)");
double tolerance = 1e-8;
int max_iterations = 20;
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") add_requires("gtest")
internal_library("surface_integral", "SI", os.scriptdir()) internal_library("surface_integrator", "SI", os.scriptdir())
add_rules("config.indirect_predicates.flags") 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 -- add Google Test target
target("newton_method_test") target("newton_method_test")
set_kind("binary") 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_files("test/SurfaceIntegrator_test.cpp")
add_packages("gtest") add_packages("gtest")
target_end() target_end()

Loading…
Cancel
Save