Browse Source

improve: blobtree subface dedup and integral calculation

- Add subface_type_offsets array to baked_blobtree for type-indexed access
- Fix subface deduplication: only add subface when not already present in map
- Simplify integral quadrature branch: use all-GL when both borders exact, all-TS otherwise
- Handle empty boarder intervals with fallback scan
V2-integral
Zhicheng Wang 2 days ago
parent
commit
25424de101
  1. 4
      blobtree_structure/interface/blobtree.hpp
  2. 12
      blobtree_structure/src/baked_blobtree.cpp
  3. 76
      surface_integral_v2/src/calculate_integral.cpp

4
blobtree_structure/interface/blobtree.hpp

@ -37,6 +37,10 @@ public:
std::vector<pointer_wrapper<subface>> subfaces{}; std::vector<pointer_wrapper<subface>> subfaces{};
std::vector<std::vector<uint32_t>> subfaces_of_primitives{}; std::vector<std::vector<uint32_t>> subfaces_of_primitives{};
std::vector<surface_type> subface_types{}; std::vector<surface_type> subface_types{};
/// subface_type_offsets[i] is the starting index of surface_type(i) in subfaces.
/// subface_type_offsets[max_count] equals subfaces.size().
/// Thus, the range of surface_type(i) is [subface_type_offsets[i], subface_type_offsets[i+1]).
std::array<uint32_t, static_cast<size_t>(surface_type::max_count) + 1> subface_type_offsets{};
public: public:
baked_blobtree_t() = default; baked_blobtree_t() = default;

12
blobtree_structure/src/baked_blobtree.cpp

@ -31,6 +31,7 @@ void recursive_bake_blobtree(baked_blobtree_t& bak
auto& node = baked_tree.nodes[max_index]; auto& node = baked_tree.nodes[max_index];
auto root_index = max_index; auto root_index = max_index;
max_index--; max_index--;
auto a = root_node->node_data.get_ptr();
if (root_node->is_primitive_node()) { if (root_node->is_primitive_node()) {
auto primitive_ptr = root_node->node_data.get_ptr(); auto primitive_ptr = root_node->node_data.get_ptr();
@ -44,12 +45,15 @@ void recursive_bake_blobtree(baked_blobtree_t& bak
auto subface_types = primitive_ptr->get_subface_types(); auto subface_types = primitive_ptr->get_subface_types();
subfaces_of_primitive.reserve(subfaces.size()); subfaces_of_primitive.reserve(subfaces.size());
for (size_t i = 0; i < subfaces.size(); ++i) { for (size_t i = 0; i < subfaces.size(); ++i) {
auto subface_ptr = subfaces[i].get_ptr(); auto subface_ptr = subfaces[i].get_ptr();
const auto& [iter, _] = subface_indices.emplace(subface_ptr, static_cast<uint32_t>(baked_tree.subfaces.size())); const auto& [iter, is_new] =
subface_indices.emplace(subface_ptr, static_cast<uint32_t>(baked_tree.subfaces.size()));
subfaces_of_primitive.emplace_back(iter->second); subfaces_of_primitive.emplace_back(iter->second);
baked_tree.subfaces.emplace_back(make_pointer_wrapper(subface_ptr)); if (is_new) {
baked_tree.subface_types.emplace_back(subface_types[i]); baked_tree.subfaces.emplace_back(make_pointer_wrapper(subface_ptr));
baked_tree.subface_types.emplace_back(subface_types[i]);
}
} }
} else { } else {
node.operation = static_cast<uint32_t>(root_node->node_data.get_mark()); node.operation = static_cast<uint32_t>(root_node->node_data.get_mark());

76
surface_integral_v2/src/calculate_integral.cpp

@ -18,6 +18,12 @@ inline uint32_t scan_interval_boarder(double l, double r, std::vector<double>& p
return std::distance(begin_iter, end_iter); return std::distance(begin_iter, end_iter);
} }
void fix_integral_boarder(std::vector<double>& cur_intervals,
const std::vector<double>& intervals_on_x0,
const std::vector<double>& intervals_on_x1)
{
}
struct chain_vertex_property_t { struct chain_vertex_property_t {
uint64_t total_count : 32; uint64_t total_count : 32;
uint64_t neg_delta_u : 8; uint64_t neg_delta_u : 8;
@ -138,23 +144,33 @@ void calculate_integral(uint8_t q,
// on boarder u = x // on boarder u = x
auto scan_u_boarder_interval = [&](double x) { auto scan_u_boarder_interval = [&](double x) {
return u_line_subface_intersection(pcurve_relation_graph, auto res = u_line_subface_intersection(pcurve_relation_graph,
subface_index, subface_index,
x, x,
subface_aabb.min().y(), subface_aabb.min().y(),
subface_aabb.max().y(), subface_aabb.max().y(),
true, true,
true); true);
if (res.size() == 2 && res[0] - subface_aabb.min().y() <= strict_epsilon
&& subface_aabb.max().y() - res[1] <= strict_epsilon)
return std::vector<double>{};
else
return res;
}; };
// on boarder v = x // on boarder v = x
auto scan_v_boarder_interval = [&](double x) { auto scan_v_boarder_interval = [&](double x) {
return v_line_subface_intersection(pcurve_relation_graph, auto res = v_line_subface_intersection(pcurve_relation_graph,
subface_index, subface_index,
x, x,
subface_aabb.min().x(), subface_aabb.min().x(),
subface_aabb.max().x(), subface_aabb.max().x(),
true, true,
true); true);
if (res.size() == 2 && res[0] - subface_aabb.min().x() <= strict_epsilon
&& subface_aabb.max().x() - res[1] <= strict_epsilon)
return std::vector<double>{};
else
return res;
}; };
auto expand_integral_on_u_ = [&](auto i, double l, double r, auto b0_iter, auto b1_iter, auto int_x, auto int_w) { auto expand_integral_on_u_ = [&](auto i, double l, double r, auto b0_iter, auto b1_iter, auto int_x, auto int_w) {
@ -325,6 +341,12 @@ void calculate_integral(uint8_t q,
auto unique_end = std::unique(intersection_u.begin(), intersection_u.end(), sorted_double_equal); auto unique_end = std::unique(intersection_u.begin(), intersection_u.end(), sorted_double_equal);
auto start_boarder_intervals = scan_v_boarder_interval(subface_aabb.min().y()); auto start_boarder_intervals = scan_v_boarder_interval(subface_aabb.min().y());
auto end_boarder_intervals = scan_v_boarder_interval(subface_aabb.max().y()); auto end_boarder_intervals = scan_v_boarder_interval(subface_aabb.max().y());
if (start_boarder_intervals.empty() || end_boarder_intervals.empty())
{
auto u0_intervals = scan_u_boarder_interval(subface_aabb.min().y());
auto u1_intervals = scan_u_boarder_interval(subface_aabb.max().y());
}
auto b0_iter = start_boarder_intervals.begin(), b1_iter = end_boarder_intervals.begin(); auto b0_iter = start_boarder_intervals.begin(), b1_iter = end_boarder_intervals.begin();
operate_on_merged_set_intervals(line_parallel_to_v.begin(), operate_on_merged_set_intervals(line_parallel_to_v.begin(),
line_parallel_to_v.end(), line_parallel_to_v.end(),
@ -332,18 +354,11 @@ void calculate_integral(uint8_t q,
unique_end, unique_end,
double_less, double_less,
[&](double l, double r, bool l_exact_gl, bool r_exact_gl) { [&](double l, double r, bool l_exact_gl, bool r_exact_gl) {
if (l_exact_gl) if (l_exact_gl && r_exact_gl)
for (auto i = 0; i < q / 2; ++i) for (auto i = 0; i < q; ++i)
expand_integral_on_v_by_gl(i, l, r, b0_iter, b1_iter);
else
for (auto i = 0; i < q / 2; ++i)
expand_integral_on_v_by_ts(i, l, r, b0_iter, b1_iter);
if (r_exact_gl)
for (auto i = q / 2; i < q; ++i)
expand_integral_on_v_by_gl(i, l, r, b0_iter, b1_iter); expand_integral_on_v_by_gl(i, l, r, b0_iter, b1_iter);
else else
for (auto i = q / 2; i < q; ++i) for (auto i = 0; i < q; ++i)
expand_integral_on_v_by_ts(i, l, r, b0_iter, b1_iter); expand_integral_on_v_by_ts(i, l, r, b0_iter, b1_iter);
}); });
// integral_plan.axis_to_expand = axis::v; // integral_plan.axis_to_expand = axis::v;
@ -361,18 +376,11 @@ void calculate_integral(uint8_t q,
unique_end, unique_end,
double_less, double_less,
[&](double l, double r, bool l_exact_gl, bool r_exact_gl) { [&](double l, double r, bool l_exact_gl, bool r_exact_gl) {
if (l_exact_gl) if (l_exact_gl && r_exact_gl)
for (auto i = 0; i < q / 2; ++i) for (auto i = 0; i < q; ++i)
expand_integral_on_u_by_gl(i, l, r, b0_iter, b1_iter);
else
for (auto i = 0; i < q / 2; ++i)
expand_integral_on_u_by_ts(i, l, r, b0_iter, b1_iter);
if (r_exact_gl)
for (auto i = q / 2; i < q; ++i)
expand_integral_on_u_by_gl(i, l, r, b0_iter, b1_iter); expand_integral_on_u_by_gl(i, l, r, b0_iter, b1_iter);
else else
for (auto i = q / 2; i < q; ++i) for (auto i = 0; i < q; ++i)
expand_integral_on_u_by_ts(i, l, r, b0_iter, b1_iter); expand_integral_on_u_by_ts(i, l, r, b0_iter, b1_iter);
}); });
// integral_plan.axis_to_expand = axis::u; // integral_plan.axis_to_expand = axis::u;

Loading…
Cancel
Save