Browse Source

fix(integrator): fix small bug in integrator

feat-integrator
mckay 2 weeks ago
parent
commit
97320c95c7
  1. 7
      surface_integral/interface/subface_integrator.hpp
  2. 39
      surface_integral/src/subface_integrator.cpp

7
surface_integral/interface/subface_integrator.hpp

@ -42,6 +42,7 @@ public:
double calculate_one_subface(const subface& subface,
const parametric_plane_t& param_plane,
const stl_vector_mp<Eigen::AlignedBox2d>& chain_bboxes,
int gauss_order,
double (*func)(double u,
double v,
@ -63,13 +64,17 @@ private:
void find_v_intersections_at_u(const subface& subface,
const parametric_plane_t& param_plane,
const stl_vector_mp<Eigen::AlignedBox2d>& chain_bboxes,
double u_val,
double v_min,
double v_max,
stl_vector_mp<double>& intersections,
stl_vector_mp<uint16_t>& intersected_chains) const;
bool is_point_inside_domain(const subface& subface, const parametric_plane_t& param_plane, double u, double v) const;
bool is_edge_inside_domain(const stl_vector_mp<stl_vector_mp<uint16_t>>& chain_group_indices,
uint16_t chain_idx1,
uint16_t chain_idx2) const;
bool is_u_near_singularity(double u, double tol = 1e-6) const;

39
surface_integral/src/subface_integrator.cpp

@ -4,11 +4,12 @@
#include <cmath> // For math functions like sqrt
#include <set>
#include <iostream>
#include <algorithm>
namespace internal
{
integrator_t(const stl_vector_mp<object_with_index_mapping<subface>>& surfaces,
integrator_t::integrator_t(const stl_vector_mp<object_with_index_mapping<subface>>& surfaces,
const flat_hash_map_mp<uint32_t, parametric_plane_t>& uv_planes)
: m_subfaces(surfaces), m_uv_planes(uv_planes)
{
@ -19,9 +20,9 @@ integrator_t(const stl_vector_mp<object_with_index_mapping<subface>>& surfaces,
for (int subface_index = 0; subface_index < m_subfaces.size(); ++subface_index) {
if (m_uv_planes.find(subface_index) != m_uv_planes.end()) {
const auto& param_plane = m_uv_planes.at(subface_index);
auto& chain_bboxs = m_chain_bboxes_hash[subface_index];
auto& chain_bboxes = m_chain_bboxes_hash[subface_index];
chain_bboxes.clear();
chain_bboxs.reverse(chain_vertices.size());
chain_bboxes.reserve(param_plane.chain_vertices.size());
for (const auto& chain : param_plane.chain_vertices) {
Eigen::AlignedBox2d bbox;
bbox.setEmpty();
@ -33,8 +34,6 @@ integrator_t(const stl_vector_mp<object_with_index_mapping<subface>>& surfaces,
}
}
}
m_chain_bboxes_hash
}
double integrator_t::calculate(
@ -46,7 +45,8 @@ double integrator_t::calculate(
if (m_uv_planes.find(subface_index) != m_uv_planes.end()) {
const auto& param_plane = m_uv_planes.at(subface_index);
const auto& subface = m_subfaces[subface_index].object_ptr.get();
total_integral += calculate_one_subface(subface, param_plane, gauss_order, func);
const auto& chain_bboxes = m_chain_bboxes_hash.at(subface_index);
total_integral += calculate_one_subface(subface, param_plane, chain_bboxes, gauss_order, func);
} else {
// the subface has no associated parametric plane, meaning it is compete face without trimming
}
@ -57,6 +57,7 @@ double integrator_t::calculate(
double integrator_t::calculate_one_subface(
const subface& subface,
const parametric_plane_t& param_plane,
const stl_vector_mp<Eigen::AlignedBox2d>& chain_bboxes,
int gauss_order,
double (*func)(double u, double v, const Eigen::Vector3d& p, const Eigen::Vector3d& dU, const Eigen::Vector3d& dV)) const
{
@ -69,9 +70,9 @@ double integrator_t::calculate_one_subface(
// Gaussian integration in u direction
auto u_integrand = [&](double u) {
// Find exact v intersections for each u
stl_vector_mp<double> v_intersections;
stl_vector_mp<double> v_breaks;
stl_vector_mp<uint16_t> intersected_chains;
find_v_intersections_at_u(subface, param_plane, u, v_min, v_max, v_intersections, intersected_chains);
find_v_intersections_at_u(subface, param_plane, chain_bboxes, u, v_min, v_max, v_breaks, intersected_chains);
// Gaussian integration in v direction
auto v_integrand = [&](double v) {
@ -104,7 +105,7 @@ double integrator_t::calculate_one_subface(
// Check midpoint validity
double mid_v = (a + b) / 2.0;
if (is_edge_inside_domain(subface, param_plane, u, mid_v)) {
if (is_edge_inside_domain(param_plane.chain_group_indices, intersected_chains[i], intersected_chains[i + 1])) {
v_integral += integrate_1D(a, b, v_integrand, gauss_order);
} else {
std::cout << "uv out of domain: (" << u << "," << mid_v << ")" << std::endl;
@ -124,7 +125,7 @@ double integrator_t::calculate_one_subface(
double mid_u = (a + b) / 2.0;
stl_vector_mp<double> v_intersections;
stl_vector_mp<uint16_t> intersected_chains;
find_v_intersections_at_u(subface, param_plane, mid_u, v_min, v_max, v_intersections, intersected_chains);
find_v_intersections_at_u(subface, param_plane, chain_bboxes, mid_u, v_min, v_max, v_intersections, intersected_chains);
if (!v_intersections.empty()) {
integral += integrate_1D(a, b, u_integrand, gauss_order, is_u_near_singularity(mid_u));
@ -165,7 +166,7 @@ stl_vector_mp<double> integrator_t::compute_u_breaks(const parametric_plane_t& p
void integrator_t::find_v_intersections_at_u(const subface& subface,
const parametric_plane_t& param_plane,
const stl_vector_mp<Eigen::AlignedBox2d>& chain_bboxs,
const stl_vector_mp<Eigen::AlignedBox2d>& chain_bboxes,
double u_val,
double v_min,
double v_max,
@ -187,9 +188,10 @@ void integrator_t::find_v_intersections_at_u(const subface&
}
// filter bbox
if (chain_bbox[chain_idx].isEmpty()
|| (chain_bbox[chain_idx].x() < u_val - 1e-8 || chain_bbox[chain_idx].x() > u_val + 1e-8)) {
chain_idx++;
const auto& box = chain_bboxes[chain_idx];
if (box.isEmpty()
|| box.max()(0) < u_val - 1e-8 // x_max < u_val - eps
|| box.min()(0) > u_val + 1e-8) { // x_min > u_val + eps
continue;
}
@ -268,14 +270,17 @@ void integrator_t::find_v_intersections_at_u(const subface&
// if (!intersections.empty()) { sort_and_unique_with_tol(intersections, 1e-8); }
}
bool is_edge_inside_domain(const stl_vector_mp<stl_vector_mp<uint16_t>>& chain_group_indices,
bool integrator_t::is_edge_inside_domain(const stl_vector_mp<stl_vector_mp<uint16_t>>& chain_group_indices,
uint16_t chain_idx1,
uint16_t chain_idx2) const
{
if (chain_idx1 >= chain_group_indices.size() || chain_idx2 >= chain_group_indices.size()) { return false; }
const auto& group1 = chain_group_indices[chain_idx1];
const auto& group2 = chain_group_indices[chain_idx2];
if (group1.find(chain_idx2) != group1.end() && group2.find(chain_idx1) != group2.end()) { return true; }
return false;
return (std::find(group1.begin(), group1.end(), chain_idx2) != group1.end())
&& (std::find(group2.begin(), group2.end(), chain_idx1) != group2.end());
}
bool integrator_t::is_u_near_singularity(double u, double tol) const { return false; }

Loading…
Cancel
Save